Sorting 如何在向已排序列表中添加少量元素时加快排序?
我有一个大约10000个元素的排序列表,我在弹出第一个元素之间插入一些元素(1-10)。测量结果显示排序过程需要几毫秒(~5),可能是因为Sorting 如何在向已排序列表中添加少量元素时加快排序?,sorting,tcl,Sorting,Tcl,我有一个大约10000个元素的排序列表,我在弹出第一个元素之间插入一些元素(1-10)。测量结果显示排序过程需要几毫秒(~5),可能是因为lsort每次都从头开始排序。现在它占用了大部分的帧时间,所以我需要做点什么 是否有一些技巧可以使合并一个大的排序列表和一个小的排序列表提高效率 用于解释上下文的代码: while {true} { set work [lindex $frontier 0] set frontier [lreplace $frontier 0 0] if {[do
lsort
每次都从头开始排序。现在它占用了大部分的帧时间,所以我需要做点什么
是否有一些技巧可以使合并一个大的排序列表和一个小的排序列表提高效率
用于解释上下文的代码:
while {true} {
set work [lindex $frontier 0]
set frontier [lreplace $frontier 0 0]
if {[done $work]} break;
set more_work [do work]; # about 1-10 elements, distribution is generally hard to predict
lappend frontier {*}$more_work
set frontier [lsort $frontier]; # when frontier is 10'000 elements time to sort is ~5ms
}
尽我所能实现一个Tcl进程,执行类似合并的排序,将发布结果。:-) 此过程将经过的时间从~5毫秒减少到~1.2毫秒:
proc merge_insert {sorted1 sorted2} {
set res {}
set prevloc 0
foreach insert $sorted2 {
# find location of next element to insert
set nextloc [lsearch -bisect -integer -index 1 $sorted1 [lindex $insert 1]]
# append up to next loc
lappend res {*}[lrange $sorted1 $prevloc $nextloc] $insert
# put read location just beyond the inserted element
set prevloc [+ 1 $nextloc]
}
# append whatever tail is left
lappend res {*}[lrange $sorted1 $prevloc end]
return $res
}
排序的属性在每个已排序元素的第二个元素中是一个整数,因此
-integer index 1
和lindex$insert 1
每次lsort
命令都进行完全合并排序;这样的插入是一个更好的选择,lsearch-bisect
就是用于此目的的工具。唉,由于Tcl列表是隐藏在封面下的简单数组,因此需要大量的拷贝才能插入,所以实际插入的成本仍然很高…