我认为 BTree 或其他传统的排序数据结构(红黑树等)不会对您有所帮助,因为它们通过键而不是对应值来保持顺序——换句话说,它们保证唯一的字段是相同的他们订购的一个。你的要求是不同的,因为你想要一个领域的唯一性,但另一个领域的排序。
您的性能要求是什么?通过基于 Python dicts 的唯一性和 Python 排序的相当简单的纯 Python 实现,在一台速度不快的笔记本电脑上,我得到了 5 秒的原始构造(基本上是对数百万个元素的排序,从它们作为 dict 开始) ,大约 9 秒用于“更新”,其中包含 20,000 个新的 id/value 对,其中一半“重叠”(从而覆盖)现有 id 和一半是新的(我可以以更快的方式实现更新,大约 6.5 秒,但是该实现有一个异常:如果“新”对之一与“旧”对之一完全相同,无论是 id 还是值,它都是重复的——防止这种“重复相同”是让我从 6.5 秒到 9,我想你需要同样的预防措施)。
这 5 秒和 9 秒的时间距离您的要求有多远(考虑到您将运行的机器的实际速度与 2.4 GHz Core Duo、2GB 的 RAM 以及这台笔记本电脑的典型笔记本电脑性能问题)正在使用)?IOW,它是否足够接近“惊人的距离”以值得修补并试图挤出最后几个周期,或者您是否需要数量级更快的性能?
我尝试了其他几种方法(使用 SQL DB,使用 C++ 及其 std::sort &c,...),但它们都比较慢,所以如果你需要更高的性能,我不确定你能做什么.
编辑:由于 OP 说这种性能很好,但他无法在任何地方实现,我想我最好展示我用来测量这些时间的脚本......:
import gc
import operator
import random
import time
nk = 1000
def popcon(d):
for x in xrange(nk*1000):
d['id%s' % x] = random.randrange(100*1000)
def sorted_container():
ctr = dict()
popcon(ctr)
start = time.time()
ctr_sorted = ctr.items()
ctr_sorted.sort(key=operator.itemgetter(1))
stend = time.time()
return stend-start, ctr_sorted
def do_update(ctr, newones):
start = time.time()
dicol = dict(ctr)
ctr.extend((k,v) for (k,v) in newones if v!=dicol.get(k,None))
dicnu = dict(newones)
ctr.sort(key=operator.itemgetter(1))
newctr = [(k,v) for (k,v) in ctr if v==dicnu.get(k,v)]
stend = time.time()
return stend-start, newctr
def main():
random.seed(12345)
for x in range(3):
duration, ctr = sorted_container()
print 'dict-to-sorted, %d: %.2f sec, len=%d' % (x, duration, len(ctr))
newones = [('id%s' % y, random.randrange(nk*100))
for y in xrange(nk*990,nk*1010)]
duration, ctr = do_update(ctr, newones)
print 'updt-to-sorted, %d: %.2f sec, len=%d' % (x, duration, len(ctr))
del ctr
gc.collect()
main()
这是一个典型的运行:
$ time python som.py
dict-to-sorted, 0: 5.01 sec, len=1000000
updt-to-sorted, 0: 9.78 sec, len=1010000
dict-to-sorted, 1: 5.02 sec, len=1000000
updt-to-sorted, 1: 9.12 sec, len=1010000
dict-to-sorted, 2: 5.03 sec, len=1000000
updt-to-sorted, 2: 9.12 sec, len=1010000
real 0m54.073s
user 0m52.464s
sys 0m1.258s
显然,总体经过的时间比我测量的总时间多几秒钟,因为它包括用随机数填充容器所需的时间,也随机生成“新数据”,销毁和垃圾收集东西每次运行结束,以此类推。
这是在具有 Mac OS X 10.5.7、2.4 GHz Intel Core Duo 和 2GB RAM 的 Macbook 上系统提供的 Python 2.5.2 (当我使用不同版本的 Python 时,时间变化不大)。