zoukankan      html  css  js  c++  java
  • python set、dict、dict.keys 性能对比

     当我们统计文本的词频时,通常需要查询当前词是否已经出现过,如果出现过,那么次数增1。通常我用dict来保存词和词频。我常用的方式是:

    if word not in vocab_dict:
        vocab_dict[word] = 0
    vocab_dict[word] += 1

    用了很久觉得速度还行。 
    后来看到有大神是这么用的:

    if word not in vocab_dict.keys():
        vocab_dict[word] = 0
    vocab_dict[word] += 1

    感觉这样似乎合理一些,因为我要做的本来就是常看word是否是vocab_map的key.于是之后都用这种方式。 
    某天,处理大量文本,且文本属于开放领域,词汇量也大,采用第二种方式,速度极慢,这时候,以为是查询dict本身比较慢,并没有意识到是vocab_map.keys()的问题。于是,将词同时存入set,查询时查set,速度快了很多。

    if word not in vocab_set:
        vocab_dict[word] = 0
    vocab_dict[word] += 1

    抽取小部分数据,量化对比set、dict、dict.keys()的查询速度,结果如下: 
    1.查询vocab_dict,打印语句:

    print "time cost is %d ms." % ((end - begin).microseconds/1000)
    time cost is 175 ms.

    2.查询vocab_dict.keys(),打印语句如下:

    print "time cost is %d s." % ((end - begin).seconds)
    time cost is 45 s.

    3.查询vocab_set,打印语句:

    print "time cost is %d ms." % ((end - begin).microseconds/1000)
    time cost is 168 ms.

    和查询vocab_dict差不多。

    那么为什么dict.keys()查询速度比另外两个慢很多呢?这就要对比list、dict、set三种的数据结构了。 
    dict.keys()实际上是list(keys),是dict的所有key组成的list。查找一个元素是否在list中是以list的下标为索引遍历list.而查询是否在dict中,是将key以hash值的形式直接找到key对应的索引,根据索引可直接访问value。对量大的dict查询,自然是后者快很多。 
    而set和dict的存储原理基本是一样的,唯一不同的是,set没有value,只有key。对查询key是否在dict或sset内,效果基本上是一样的。

    由此,可以得出,如果存储的数据会被反复查询,且量大,那么,尽量不要用list,尽量用dict,如果元素不重复,用set更好。查询是否在dict内,也不要在用dict.keys()
     

    关注公众号 海量干货等你
  • 相关阅读:
    软件命名规则
    从命令行git转到Tortoise
    如何让浏览器不解析html?
    说几点我觉得谷歌浏览器不好的地方
    移动端开发:使用jQuery Mobile还是Zepto
    开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    给大家讲个故事,感受一下什么叫CF。不知道的请认真听。
    cmd中utf-8编码的问题
    web前端关于html转义符的常用js函数
    js实例分析JavaScript中的事件委托和事件绑定
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734211.html
Copyright © 2011-2022 走看看