C++大战Python - 以C++11重写欢乐斗地主残局解答器

系统 188 0

业界传说Python平均一行代码能够顶的上几十行C/C++代码。业界还传说,C++效率能够达到Python的几十倍。
对于以上二者,笔者本来感觉也许差不多只是略夸张。笔者曾经用C++和Python分别实现了不带cache的求Fibonacci数的函数,大约C++的效率确实可以达到Python效率的几十倍,不过代码量没有几十倍,只是略多。但这个毕竟是toy programming,如果是在一个真正实用性的项目当中,C++和Python在效率以及代码量上的对比究竟几何呢?笔者做了一个实验。

大约一年多前,笔者利用过年的时间,用Python实现了一个微信欢乐斗地主的残局解答器,还写了一篇CSDN博文,详见《做一个微信欢乐斗地主之残局解答器!》, 代码见GitHub:https://github.com/FinixLei/WeChat_LandLords/tree/master/Python 
时隔一年,笔者又利用今年的五一假期的业余时间,用C++11将这个残局解答器重写了一遍,新代码在GitHub的这里:https://github.com/FinixLei/WeChat_LandLords/tree/master/Cpp 

期间有一些心得,记录如下。

1. 实现选型与新老程序对比

关于实现选型,鉴于C++11已经出来很久了,而且很明显,C++11的一些特性如auto等,对缩短代码量很有好处,因此C++11是不二之选。
新老程序在实现的逻辑和算法上是比较接近的,否则进行代码量和效率的对比也就没有意义了。故此,笔者没有对C++代码做特别优化。 C++11的实现虽然Fix了Python实现里的几个bug,但都是比较小的bug,并不影响正确性,只是对效率有那么一点可以忽略不计的影响。所以,原Python程序在正确性上还是比较可靠的。
 但是, 关于多线程实现的选型,笔者尝试了C++11多线程和POSIX的pthread系列之后,最终还是选择了libpthread来实现多线程程序。C++11的多线程似乎是有一些坑的 ,而pthread实现起来还是可以的,并不繁杂。毕竟,要做一个平台无关的语言级多线程不是那么容易。这其中,比较重要的一两个坑,笔者已经写在前一篇博客里了,参见《C++11多线程的局限》.
   

2. 代码量的对比

   

  功能性代码(行) 测试代码(行)
C++11 1706 639
Python 1215 289

从功能性代码来看, C++11比Python多了刚好40%,并不是业界传说的几十倍。

 

3. 效率的对比

 一般的残局题目C++实现都是1秒左右给出答案,而Python也是秒级,看不太出来准确的区别。故笔者找到几个难一点的题目,以一台阿里云的双核四线程的ECS测下来,计算时间如下。
 

  case-1 case-2 case-3
Python 37.59 秒 152.57 秒 237.08 秒
C++11 2.41 秒 12.68 秒 8.99 秒
倍数 15.60 倍 12.03 倍 26.37 倍

值得注意的是,编译的时候需要加-O2选项以做优化。如果不加该选项,效率会差6倍左右(谢谢网友qq_24038061指出原文疏漏之处)。

测试用例如下:
case-1:
   人类的牌(地主): "小王 大王 K 10 10 7 8 8 6 6"
   电脑的牌(农民): "2 2 A A A 9 9 7 6 6 3 3"

case-2:
   人类的牌(地主): "2 2 A Q J 9 9 6 6 4"
   电脑的牌(农民): "大王 A K K Q J J 10 8 8 7 4 4"

case-3:
   人类的牌(地主): "2 Q 9 7 6 6 5 5 4"
   电脑的牌(农民): "K K Q J 10 9 7 6 6 4 3 3"

可见,效率是在 12-26倍 之间。
   
综上所述,就本项目而言,
Python写起来爽,代码量是C++11的70%左右,但效率却真的只有C++的十几分之一到几十分之一!

(完)
 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请请扫描上面二维码支持博主1元、2元、5元等您想捐的金额吧,狠狠点击下面给点支持吧

发表我的评论
最新评论 总共0条评论