与删除字典中的对象相关的性能

时间:2017-07-13 17:39:36

标签: python python-2.7 python-3.x

我有一个字典,我不断添加和删除指向类对象的键。反过来,这些类对象不断被创建和销毁。在我的实际系统代码中,我最初只是在没有清理它们的情况下添加对象(遗留代码),当我开始删除它们时,我开始看到比我预期的更缓慢,所以我想知道:

  1. 删除对象的效果是否取决于对象尺寸

  2. 在字典中删除对象的效果是否取决于对象尺寸

  3. 在词典中删除对象的效果是否取决于词典大小

  4. 是否有更好的存储易失物品的策略? (大约10000个对象)

  5. 下面我只提供了一些我尝试和测试的基本代码,但是删除的时间是决定性的。一个解释器(PyCharm)会说两个删除都需要0秒,而我的VM交替说一个将需要0秒而另一个需要一个微秒,然后下一个迭代将切换。我不确定"大"我需要制作东西,或者这是否也是正确的方法。

    import time
    
    def foo():
        a = dict()
        a[0] = 1
        a[1] = bar()
        return a
    
    class bar:
        def __init__(self):
            self.val = dict()
    
    o = foo()
    
    time0 = time.time()
    del o[0]
    time1 = time.time()
    del o[1]
    time2 = time.time()
    
    print(time1-time0)
    print(time2-time1)
    

1 个答案:

答案 0 :(得分:2)

我对这两个问题做了一些测试:

  1. 删除对象的性能是否取决于对象的大小?
  2. 删除字典中对象的性能是否取决于对象的大小?
  3. 第一个问题很难回答。删除1项是如此之快,我们不能"基准"很容易尽管如此,第二个问题也可以回复第一个问题,因为差异仍然只取决于价值的大小。 为此,我使用了以下脚本。

    import random
    import string
    import time
    
    def generate_string(l):
        return "".join([ random.choice(string.ascii_letters) for _ in range(l)])
    
    group_short = {}
    group_long = {}
    
    for i in range(50000):
        group_short[i] = generate_string(5)
        group_long[i] = generate_string(500)
    
    t_short = time.time()
    for i in range(0, 50000, 3):
        del group_short[i]
    print(time.time()-t_short)
    
    t_long = time.time()
    for j in range(0, 50000, 3):
        del group_long[j]
    print(time.time()-t_long)
    

    不幸的是,生成dictionnaray需要花费更多时间而不是删除一些项目,因此我无法用非常大的样本对其进行测试。 "估计"对于较小的对象,结果快了大约25%(这有点奇怪,因为对象存储为引用而不是值):

    1. 0.00200s短物件
    2. 0.00250s,包含更大的物品

    3. 删除字典中对象的性能是否取决于字典的大小?

    4. 对于这个,我生成了相同大小的字符串,但group_short包含5000个对象,group_long包含150000个对象。我删除了相同数量的项目,结果就是:

      1. 0.00047s for the short dict
      2. 长dict的0.00150s
      3. 基于此,我们可以假设词典的长度会影响删除项目的时间

        1. 是否有更好的存储易失物品的策略? (大约10000个对象的顺序)
        2. 为此,我不了解所有存在的数据类型的所有知识。尽管如此,该结构实际​​上已经过优化,可以根据已知密钥(O(1)的复杂度)尽可能快地访问。如果您的密钥是基于范围的整数,那么numpy数组可能是更快的更新/访问值。这仅取决于您要存储的对象(int,float,bool,class,string等)。有些类型在Numpy中无法访问。

          我希望它有所帮助,

          CONI