欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[VB.NET Tips]再谈字符串连接之内置池

程序员文章站 2022-07-20 10:07:24
CLR自动维护一个称为”内置池“(暂存池)(intern pool)的表,在编译时此表包含程序中声明的每个唯一的字符串常量的单个实例,以及以编程方式创建的String类的任何唯一实例。 内置池被实现为散列表。使用散列表即表示,一个字符串可以通过一个数字或”散列码“来表示。这样比较和搜索字符串就非常有 ......

clr自动维护一个称为”内置池“(暂存池)(intern pool)的表,在编译时此表包含程序中声明的每个唯一的字符串常量的单个实例,以及以编程方式创建的string类的任何唯一实例。
内置池被实现为散列表。使用散列表即表示,一个字符串可以通过一个数字或”散列码“来表示。这样比较和搜索字符串就非常有效,因为这不是逐个字符比较字符串,而仅仅比较散列值。
内置池节省字符串存储空间。如果将一个字符串常量赋给几个变量,则每一个变量引用内置池中相同的常量,而不是引用具有相同值的string类的几个不同实例。

可以测试如下代码:

    const appname as string = "运维应用程序"

    console.writeline(string.isinterned(appname) <> nothing)

    dim s1 as string
    dim s2 as string

    s1 = "这是一个测试的字符串"
    s2 = "这是一个测试的字符串"


    console.writeline(string.isinterned(s1) <> nothing)
    console.writeline("s1的散列值:{0}", s1.gethashcode())
    console.writeline("s2的散列值:{0}", s2.gethashcode())

    dim s3 as string = s1 & datetime.now().tostring()
    console.writeline("s3的散列值:{0}", s3.gethashcode())
    console.writeline(string.isinterned(s3) <> nothing)

运行以下代码会发现.net会内置了包含字符串常量,以及编程方式创建的字符串。
会发现s1和s2引用同个字符串实例。s3不会被内置,因为在编译时并不能确认s3的具体内容。也可以使用string.intern强制内置一个变量。
用图来表示一下:
[VB.NET Tips]再谈字符串连接之内置池

那么内置有什么好处呢,对比下面的代码,第二个方法比第一个方法快3倍以上。

     sub main()
        console.write("请输入你的名字:")
        dim username as string = console.readline()

        method1(username)
        method2(username)

        console.read()

    end sub

    public sub method1(byval username as string)

        dim strhtml as string

        '每次循环创建3次字符串,分配3次内存
        dim startms as integer = environment.tickcount()
        for i as integer = 1 to 1000000
            strhtml = "<html><head></head><body>"
            strhtml &= "我的名字是:"
            strhtml &= username
            strhtml &= "</body></html>"
        next
        dim endms as integer = environment.tickcount()

        console.writeline("总耗时:{0}微秒", (endms - startms))

    end sub
    public sub method2(byval username as string)

        dim strhtml as string
        const strprefix as string = "<html><head></head><body>"
        const strsuffix as string = "</body></html>"

        '只创建一次字符串
        dim startms as integer = environment.tickcount()
        for i as integer = 1 to 1000000
            strhtml = strprefix & "请输入你的名字:" & username & strsuffix
        next
        dim endms as integer = environment.tickcount()

        console.writeline("总耗时:{0}微秒", (endms - startms))

    end sub

以上方法只是抛砖引玉,在实际应用中灵活应用。在一些web应用程序中有大量字符串拼接操作的,可以多使用内置。毕竟处理速度快,能够处理的并发就越高。