Python的速度:文本文件取交
原创:nasi一个资深工程师曾经跟我说:他对Python很失望。原因就是Python的速度他实在不能忍受。对于一种动态语言,我本来也没有对速度抱有多大的希望。但是,没有试过,并没有数据可以拿来说话。所以接下来我会用一些方法来测试一下Python的速度究竟如何。当然不是单纯的比较,而是放在实际问题下来比较。当然,方法也不保证一定科学,但是会尽量保证公平。对于和Python比较的方法,我会选择开发效率高的解决方案,C语言在200行左右的方案就不加考虑了,而shell/awk这种几行就能解决的方法正是要拿来比较的。因为这些方法正是因为开发效率高,所以很是常用。
这次的实际问题是:有两个文本文件,每个都是10万行,文本文件的大小在100M左右。现在需要知道这两个文件取交有多少行,即是说,有多少行同时在两个文件中存在。这里每个文本文件都经过去重,所以本身没有重复的行。这里待比较的三个方法是shell、awk和python。其中bash和awk的方法是非常常用的,所以我想知道究竟python的速度是怎样的。
评测环境
评测环境是一台Dell D630笔记本,Intel Core2 Duo(1.80GHz)的CPU,内存1G。评测数据是用Python随机生成的文本文件。
shell方法
用shell,一行代码就可以搞定这个需求:
cat uniq.data.1 uniq.data.2 | sort | \
uniq -c | awk '{if($1==2) c++} END {print c}'
三次测速的结果如下:
9.344s 10.053s 9.751s
平均结果:9.716s
awk方法
下一个方法是用awk来实现,awk的解决方法也很简单:
gawk '{if(ARGIND==1)d[$1]=1; else if($1 in d)c++} END{print c}' \
uniq.data.1 uniq.data.2
三次测速的结果如下:
2.266s 2.334s 2.349s
平均结果:2.316s
Python方法
Python的方法需要的行数多一些,不过还好只有5行。虽然可以在一行内搞定,只是这样会让程序变慢一点点,所以还是分开来写:
1
2
3
4
5
6
7
data1 = open("uniq.data.1").readlines()
data2 = open("uniq.data.2").readlines()
a = set(data1)
b = set(data2)
print len(a & b)
三次测速的结果如下:
1.235s 1.229s 1.212s
平均结果:1.225s
结论
说实话结果很出乎我意料之外,我没有想到Python居然是最快的方法,比起我们平时经常使用的awk还要快,而且快了近一倍左右。况且Python是这几个方法中最为优雅、最可读的方法,让我对Python的看法有了很大的改观。 python2.4后引入的set类型是C实现的,用的hash算法也很好,至少比sgi stl的hash_set好。
代码还可以写的更短。
a = set(open(”uniq.data.1″))
b = set(open(”uniq.data.2″))
print len(a & b)
直接将文件句柄传给set的话,就可以得到lazy read的好处,更快更省内存。
这个测试只能说明py在文本处理上效率比较好,但在其他方面就不是让人满意了,至少比不上java
页:
[1]