我还使用该time
命令进行基准测试。这是我的代码,我添加了另外两种方法,一种用于使用array
,另一种用于struct::set
消除重复。
#!/usr/bin/env tclsh
#http://stackoverflow.com/questions/18337534/what-way-is-faster-to-populate-a-list-with-unique-values-in-tcl
package require Tclx
package require struct::set
proc removeDupMethod {selectionList} {
set finalList [list ]
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
lappend finalList $i
}
}
set finalList [lrmdups $finalList]
return $finalList
}
proc searchBeforInsertMethod {selectionList} {
set finalList [list ]
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
if {[lsearch $finalList $i] == -1} {
lappend finalList $i
}
}
}
}
proc useArrayMethod {selectionList} {
array set tally {}
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
incr tally($i)
}
}
set finalList [array names tally]
return $finalList
}
proc useStructSetMethod {selectionList} {
set finalList {}
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
struct::set include finalList $i
}
}
return $finalList
}
# Performs the benchmark on a method
proc bench {methodName} {
set selectionList {1:10 5:20 10:30 4:30}
set timeInfo [time {$methodName $selectionList} 1000]
puts "$methodName - $timeInfo"
}
# main
bench removeDupMethod
bench searchBeforInsertMethod
bench useArrayMethod
bench useStructSetMethod
结果:
removeDupMethod - 281.961364 microseconds per iteration
searchBeforInsertMethod - 93.984991 microseconds per iteration
useArrayMethod - 122.354889 microseconds per iteration
useStructSetMethod - 576.293311 microseconds per iteration
讨论
- 您的第二种方法 ,
searchBeforInsertMethod
是最快的。
useArrayMethod
,它使用数组来确保唯一性,排在第二位。这就是说TCL的内置列表命令是非常优化的。
- 令我惊讶的是,这
useStructSetMethod
是最慢的。我认为应该优化库命令,但我错了。
更新
我接受了 Siyb 的提示并替换:
regexp {(\d+):(\d+)} $selection -> start end
和:
set range [split $selection :]
set start [lindex $selection 0]
set end [lindex $selection 1]
并看到速度显着提高:
removeDupMethod - 9.337442 microseconds per iteration
searchBeforInsertMethod - 5.528975999999999 microseconds per iteration
useArrayMethod - 6.8120519999999996 microseconds per iteration
useStructSetMethod - 5.774831 microseconds per iteration
useNative - 6.105141 microseconds per iteration
笔记
- 最快的还是
searchBeforInsertMethod
,速度提升近17倍。
useStructSetMethod
现在上升到第二位
更新 2
根据 potrzebie 的要求,我在开头添加了 5000:6000 并且数字变化不大:
removeDupMethod - 10.826106 microseconds per iteration
searchBeforInsertMethod - 6.296769 microseconds per iteration
useArrayMethod - 7.752042 microseconds per iteration
useStructSetMethod - 6.910305999999999 microseconds per iteration
useNative - 7.274724 microseconds per iteration