在什么样的数据结构中实现了TCL的阵列?

时间:2015-03-28 13:35:27

标签: arrays tcl

在TCL中处理非常大的日期我想知道在数组中搜索的速度有多快。不幸的是,数组中的填充过程并不像其他着名的脚本语言那样执行。

2 个答案:

答案 0 :(得分:4)

Tcl称为“数组”的数据结构是从字符串值到变量的关联映射(它被认为是变量的,因为它有一个名称和你可以做一些高级的事情,比如附上trace。在引擎盖下,它是一个哈希表(实际上它是所有哈希表中最快的哈希表实现之一),因此随着元素数量的增加,它可以很好地扩展。

但它与您在C,Java,C#,Python等语言中找到的数组不一样...... Tcl中最接近匹配的那些是 list < / em>,这是一个值(无名,可自动序列化),它保存从“小”整数(即索引)到值的紧凑映射。它的重量比Tcl阵列轻得多(事实上,它是使用C阵列实现的)。

他们不支持同一组操作。实际上,Tcl中的第三个数据结构需要注意:字典。这是一个从字符串到值的关联映射值。它也是使用哈希表(使用Tcl用于数组的相同超快速算法)实现的,尽管有一些自定义,因此有一个固定的迭代顺序(插入顺序,因为它&#39;当你往返序列化时,s得到了很好的属性。)

您可以将列表放在列表中的词典和词典中。您可以将其中一个放入数组元素中。但是你不能将数组(或数组的元素)放在列表​​或字典中;你可以做的最好的事情是把数组的名称放入(因为它只是一个普通的旧字符串)。


性能比较

列表创建速度最快(尤其是使用lrepeat)并且具有快速更新和快速查找操作。如果您按索引工作。搜索内容需要进行线性扫描。

阵列和词典的创建速度较慢 - 这是最慢的取决于完全你正在做什么 - 但它们都支持超快速查找和按键更新。 (对密钥的存在进行测试也会进行查找;它在算法上几乎与读取相同。)搜索特定有效负载的存在仍然慢;它仍然需要线性扫描。

注意在Tcl中计时:总是时间调用一个过程,因为程序比免费代码更加优化。

proc doStuffList {size value1 value2} {
    for {set i 0} {$i < $size} {incr i} {
        lappend theList $i
    }
    return [list [lindex $theList $value1] [lindex $theList $value2]]
}
proc doStuffDict {size value1 value2} {
    for {set i 0} {$i < $size} {incr i} {
        dict set theDict $i $i
    }
    return [list [dict get $theDict $value1] [dict get $theDict $value2]]
}
proc doStuffArray {size value1 value2} {
    for {set i 0} {$i < $size} {incr i} {
        set theArray($i) $i
    }
    return [list $theArray($value1) $theArray($value2)]
}

puts "lists: [time {doStuffList 500 150 450} 1000]"
puts "dicts: [time {doStuffDict 500 150 450} 1000]"
puts "arrays: [time {doStuffArray 500 150 450} 1000]"

在这台笔记本电脑上,我得到了这个输出:

lists: 58.565204 microseconds per iteration
dicts: 114.074002 microseconds per iteration
arrays: 118.863908 microseconds per iteration

但请注意,哪个是最佳选项取决于完全有关您正在做什么的详细信息。使用最适合您算法的数据结构;拟合良好将确保它对你有好处。

答案 1 :(得分:0)

这是一个简单的测试,显示了数组和列表性能。我的初步测试显示列表填充速度比数组快。数组会在搜索时间内获得一些速度。

array.tcl

#!/usr/bin/tclsh

set array_time [time {
        array unset my_array
        for {set i 0} {$i < 365} {incr i} {
                set "my_array($i)" $i
        }
        set a [info exists my_array(180)]
        set b [info exists my_array(366)]
} 100]

set list_time [time {
        set my_list [list]
        for {set i 0} { $i < 365} {incr i} {
                lappend my_list $i
        }
        set x [lsearch $my_list 180]
        set y [lsearch $my_list 366]

} 100]

puts "$a, $b"
puts "$x, $y"

puts "array: $array_time

输出:

% ./array.tcl
1, 0
180, -1
array: 360.54830999999996 microseconds per iteration
list: 362.89529000000005 microseconds per iteration