python有多慢?python vs c++

Python有多慢?

最近做一些和性能相关的东东,因为被python惯坏了,实在不想用编写和调试复杂十倍而且很遗憾我已经好久不用快忘光的C/C++,但是又怕python会造成大的瓶颈,所以对python的性能很好奇。
`
随处搜了一下,这篇关于 Ruby/Java/Python/PHP性能比较: http://www.blogjava.net/shinewang/archive/2009/01/20/251600.html
它得出结论PHP : JRuby : Python : Java 大约是 1:2:4:100,这个结论令我有点不敢相信,我一直以为python是效率仅次于java的厉害家伙呢。(嘛,虽然这个结果好像python确实仅次于java@@)这让人有点不太放心用python写代码了,写出乌龟来也太过糟糕。

以前我做过一次php和C++浮点运算的比较,结果C++比php快500倍,可是谁会去用php来做浮点运算?我不太明白1:2:4:100的数据是如何得出的,所以决定亲自测一下python和C++的速度对比。

实验设计:

1.选择相同的数据结构进行实现,比较性能。这里我选择了Splay树,因为网上有现成的代码。
2.选择相同的实际应用进行实现,比较性能。这里我选择了统计词频这个老土应用,对象是python 2.6.4纯文本文档。

实验目的:

1.分析python语言本身的性能
2.因为python基本上是个模块就是用c写的库,所以我们还是要看看实际应用中库的表现,实验2可以理解为C++的STL库 vs python的库,也是一般的实际应用场景。

实验一:Splay Tree

代码偷懒了没有自己写,所以比较可能有偏差
Pysplay: http://code.google.com/p/pysplay/
C++ SplayTree: http://users.cis.fiu.edu/~weiss/dsaa_c++/code/
`
测试项目:10000个随机数进行insert
分数:

python2.6.4: 0.537045955658
python+psyco: 0.45485496521
G++ 4.4.1: 0.0056
G++ -O3: 0.0034

结论:
100倍,是的,当时就是这样,我被震了,python本身果然很慢。

实验二:统计词频

这个我先是下载了 http://docs.python.org/ftp/python/doc/current/python-2.6.4-docs-text.tar.bz2 ,然后自己用合并成了一个大文件 full.txt

cat `find . -type f` > full.txt

然后分别写了统计词频的源码。
python版本:

import re
import timeit
 
#uncomment if test with psyco
#import psyco
#psyco.full()
 
def top10word():
    '''return 10 most frequently used word in python 2.6.4 docs'''
    txt = open('full.txt','rb').read()
    lst = re.compile(r'[A-Za-z]+').findall(txt)
    d = {}
    for word in lst:
        word = word.lower()
        if d.has_key(word):
            d[word] += 1
        else:
            d[word] = 1
    sd = sorted(d.items(),cmp=lambda x,y:cmp(y[1],x[1]))
    return sd[:10]
 
if __name__ == '__main__':
    print top10word()
    t = timeit.Timer('top10word()','from __main__ import top10word')
    print t.timeit(number=1)

然后是C++ STL版本的

#include <iostream>
#include <fstream>
#include <string.h>
#include <ctype.h>
#include <vector>
#include <algorithm>
#include <ext/hash_map>
#include <stdio.h>

namespace __gnu_cxx{
  template<> struct hash< std::string >        {
    size_t operator()( const std::string& x ) const                {
      return hash< const char* >()( x.c_str() );
    }
  };
}
using namespace std;
using namespace __gnu_cxx;

typedef pair<string,int> dpair;

bool sort_second(const dpair & left, const dpair & right){
  return left.second > right.second;
}

int main(){
  hash_map<string, int> d;
  string line;
  // read file
  FILE* pFile = fopen("full.txt","rb");

  fseek (pFile , 0 , SEEK_END);
  int lSize = ftell (pFile);
  rewind (pFile);

  char *buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
  int result = fread (buffer,1,lSize,pFile);

  // creating hash_map
    int i = 0;
    while( i < lSize ){
      // read the line, put word into map
      char word[100]; // I guess it's long enough
      while( i < lSize ){
        // skip nonalphas
        while ( !isalpha(buffer[i]) && i < lSize )
          i++;
        if ( i == lSize )
          break;
        // pick a lower-cased word
        int j=0;
        while ( isalpha(buffer[i]) )
          word[j++] = tolower(buffer[i++]);
        word[j] = '\0';
        // push into the hashmap
        string w = string(word);
        if ( d.find(w)!=d.end() )
          d[w]++;
        else
          d[w]=1;
      }
    }
  // transform to vector<pair<string,int>>
  vector<dpair> vd;
  for( hash_map<string,int>::iterator it=d.begin();it!=d.end();++it ){
    vd.push_back(dpair(it->first,it->second));
  }
  // sort
  sort(vd.begin(),vd.end(),sort_second);
  cout << clock() << endl;
  int count = 0;
  for( vector<dpair>::iterator it = vd.begin(); count<10; count++,it++ ){
     cout << it->first << ":" << it->second << ";";
  }
  cout << endl;
  return 0;
}

测试数据:

py:              0.942732095718
py+psyco:          0.70565700531

STL hash_map:          0.700
G++ -O3:         0.320

结论:
在实际应用中,python并不会比C++慢多少,慢的这点速度完全可以由其开发速度弥补。
`
经过这次测试,我彻底地体会到了所谓开发速度的差距:python的那个我记不得has_key函数的名字了,于是直接在python的shell里面试验了一下,花了20秒钟,其他基本无调试,一次通过。整个程序加调试加定稿加起来大概也就5-10分钟吧。
`
C++那个,开始死活编译不过去,后来google了一下,发现问题,改代码;又出问题,又改,当然也有我太久不用(尤其是STL,C还有时候用用,STL真是太久没有用过了)忘记的原因,不过这个折磨加煎熬啊,以后我再也不和C++比了,我和java比还不成么,泪奔……

This entry was posted in python, 编程 and tagged , , . Bookmark the permalink.

10 Responses to python有多慢?python vs c++

  1. est says:

    python足够快了,真要性能脚本语言选LuaJIT2。

  2. upsuper says:

    性能嘛……Lua 应该是脚本中最快的了,不过 Python 其实已经很好了~而且时间热点再用 C 改写一下,执行效率和开发效率就取完美平衡了~

  3. 博主很有实验和独立思考的精神啊~~佩服@!
    刚学python,博主能说说初学者提升功力的一些经验吗?

    • observer says:

      多实战啊,想个东东出来写,会遇到很多问题,google之,又有很多问题…
      实战是很有意思的,一些思路:用python写socket程序,比如聊天程序;写小说/漫画下载打包程序;写写windows小游戏比如扫雷搬运工俄罗斯方块等等…
      对了解决问题时最好用google.com来搜索,GFW是必须绕过去的,这方面毕竟国外的资料多一些。百度这种垃圾就别用了,越用越菜。

  4. alibudae says:

    博主可以在simplecd的源代码项目多些说明吗,想学习python,最想学的就是其中的爬虫,所以对simplecd很感兴趣,但是对python刚入门,希望能多些介绍。同时能提供代码打包下载,svn那种东西不太懂

    • observer says:

      这个,python语法太直观了,我都觉得不用注释就差不多了,simplecd的爬虫部分可以结合我发过的一篇爬虫总结一起看,就是fetchvc.py这么一个文件中的fetch()函数部分,基本没有多少行的,其他跟爬虫无关,都是一些控制语句什么的。
      svn?我用的是mercurial,windows也有客户端的,用起来非常之简单,去学吧,很快的,太懒可学不会东西。

  5. 小宇 says:

    楼主认为 JAVA python c++ 哪个更适合学习?
    哪个网络应用方面更多一些呢?

  6. ym says:

    gappproxy可移植到自己的vps 吗

  7. jetsanix says:

    额。。这种对比数据毫无意义嘛。。

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">