话说为什么大家会集中讨论GIL?在这里题主的标准线是一个按bit处理的单线程DFS啊……几乎没有GIL发挥的余地好么……

这个八皇后的DFS,我的C++代码在不加某些评估性剪枝的情况下对15需要算18s左右(开O2大约8.6秒,与题主描述基本一致),但是可以确定的是你的解决方案里用了循环与递归。接下来需要分析的无非是Python慢在哪个细节,以及能否改进的问题。

下面是两段用来测试的代码,首先是Python的:

#!/usr/bin/env python3

import time

def calc(n, i=0, cols=0, diags=0, trans=0):

if i == n:

return 1

else:

rt = 0

for j in range(n):

col = 1 << j

diag = 1 << (i - j + n - 1)

tran = 1 << (i + j)

if (col & cols) == 0 and (diag & diags) == 0 and (tran & trans) == 0:

rt += calc(n, i+1, cols | col, diags | diag, trans | tran)

return rt

if __name__ == '__main__':

t = time.time()

print(calc(13))

print(time.time() - t)

以及C++代码:

#include

#include

using namespace std;

long calc(int n, int i = 0, long cols = 0, long diags = 0, long trans = 0) {

if (i == n) {

return 1;

} else {

long rt = 0;

for (int j = 0; j < n; j++) {

long col = (1 << j);

long diag = (1 << (i - j + n - 1));

long tran = (1 << (i + j));

if (!(col & cols) && !(diag & diags) && !(tran & trans)) {

rt += calc(n, i + 1, col | cols, diag | diags, tran | trans);

}

}

return rt;

}

}

int main() {

auto t = chrono::system_clock::now();

cout << calc(13) << endl;

cout << (chrono::system_clock::now() - t).count() * 1e-6 << endl;

return 0;

}

这里的C++代码没按照OOP去写,怎么简单怎么来吧……

测试机器配置是Core i7 4870HQ,编译器用的Clang++ 8.1.0,Python解释器则是CPython 3.6.0。没测试15的数据量只测试一下13,因为15太费时间了……

由于这里压根不涉及多线程问题,那基本上就跟GIL没有半毛钱关系了。

对于n=13,C++代码跑了0.48秒。为了确保不是编译器悄悄干了活,我特地打成了-O0(实际上开O2能到0.2秒左右)。Python跑了24秒。

对于这个例子,最直接的影响其实在于:Python是逐句解释执行的,C++是先编译成本地代码,期间还有编译期的类型检查,不存在动态类型、动态检查,并且可以进行编译器优化。

之后应该考虑一下能不能提高一点点效率呢?

然后根据一般规律,Python的循环很慢,我们可以考虑改成列表展开:

def calc(n, i=0, cols=0, diags=0, trans=0):

if i == n:

return 1

else:

return sum(

[

calc(n, i + 1, cols | (1 << j), diags | (1 << (i - j + n - 1)), trans | (1 << (i + j)))

for j in range(n)

if (cols & (1 << j)) == 0 and (diags & (1 << (i - j + n - 1))) == 0 and (trans & (1 << (i + j))) == 0

]

)

理应速度更快,实时也验证了:这样的Python代码需要跑18秒左右。仍然存在数量级的差异,并没有解决根本问题,但是说明了一点,CPython中for loop的实现其实一点都不快。

而后考虑一下,如果我们使用其它解释器,特别是包含JIT的解释器,它将在执行过程中尝试将代码编译成本地二进制编码并执行,同时还能赋予一些额外优化,会不会好很多?

那么单纯地尝试一下PyPy3(5.8.0-beta, Python 3.5.3),代码能有多快?

实际上,单纯的只是替换一下解释器,换成PyPy来做的话,原本这个24s的Python源码就只需要1s左右了。单单一个JIT可以使得性能提升一个数量级,充分说明官方的CPython解释器的性能真心很烂……

PyPy的JIT比较简单纯粹,并不是很激进,但是同样的代码如果能借助更好的JIT,以及更高性能的库,则可以体现出完全不同的性能差。例如,如果使用llvm做JIT,同时加上能使用一些成熟的数学库做优化。我们知道NumPy这样的C扩展能够很大程度提高Python做数值计算的性能,同样的我们也可以用Cython或者直接用C写Python扩展来强化计算能力。但是人都是懒的,重新写代码实在是有些麻烦。对于Python这种生态强大的玩意来说,如果你的计算代码中只是单纯的使用了numpy的简单结构以及Python自身的标准结构,使用numba可能是最简单快速的办法。

#!/usr/bin/env python3

import time

from numba import jit

@jit

def calc(n, i=0, cols=0, diags=0, trans=0):

if i == n:

return 1

else:

rt = 0

for j in range(n):

col = 1 << j

diag = 1 << (i - j + n - 1)

tran = 1 << (i + j)

if (col & cols) == 0 and (diag & diags) == 0 and (tran & trans) == 0:

rt += calc(n, i+1, cols | col, diags | diag, trans | tran)

return rt

if __name__ == '__main__':

t = time.time()

print(calc(13))

print(time.time() - t)

这里只是很简单地加入了两行代码:从numba导入jit,用jit装饰我们的计算函数。这段代码的运行时间直接就缩短到了0.4s,和C++版本的O0编译后的程序速度几乎一样。这还是考虑到JIT需要预热的情况在内。这段代码,若是计算15的规模,只需要6.5s左右,甚至优于开O2的C++版本。

究其原因,JIT不仅仅在运行过程中将代码转为本地机器码,同时还会尝试进行优化。如果用cProfile之类的玩意分析一下运行过程,可以清楚看到这个优化过程。

python那么慢为什么还有人用-为什么Python比C++慢很多?相关推荐

  1. python那么慢为什么还有人用-为什么Python运算慢还拿来搞AI?这三点大多数都不知道?...

    首先慢是相对的.之前大家对python慢的理解,其实是因为那时候的机器资源有限,相对于c/c++这样可以直接操作内存的语言,python需要占用更多的内存,因此会慢.但是现在机器硬件成本已经可以忽略的 ...

  2. python那么慢为什么还有人用-为什么Python如此慢

    Python当前人气暴涨.它在DevOps,数据科学,Web开发和安全领域均有使用. 但是在速度方面没有赢得美誉. 这里有关于Python比较其他语言如,Java, C#, Go, JavaScrip ...

  3. python学什么版本2020年_2020年了居然还有人在学Python?学python有什么用?

    都2020年了居然还有人在学python?学python有什么用? 真是气抖冷啊! 想学习python的小伙伴,可以加裙595227871 领取免费的学习资料 为什么选择python? 1.行业人才的 ...

  4. fortran语言和python语言_fortran语言还有人用吗

    fortran语言还有人用吗? Fortran还是有人用的,不过一般是科学计算方面用得多一些. 它是世界上最早出现的计算机高级程序设计语言,广泛复应用于科学和工程计算领域.毕竟一个语言的存在自然有它的 ...

  5. python那么慢为什么还有人用-Python执行效率慢,为什么还这么火?【黑马程序员】...

    稍微了解python的同学,都知道python比起java这类编译型语言来说执行效率比较低,可是为什么python依然这么火呢? Python是一门解释型的动态语言,由于语言的解释执行的过程和动态类型 ...

  6. python那么慢为什么还有人用-为什么大家都说python编程的效率速度慢呢?

    今天的python培训想和大家分享一下python编程语言慢的原因,让大家采取一些措施避免其缺陷,希望对大家有所帮助! 近年来Python语言开始流行.它广泛应用于网络开发和运营.数据科学.网络开发和 ...

  7. python学到什么程度可以找到工作-Python学到什么程度可以面试工作?

    0710更新: 不多说,上干货!!!最近得到了一张比较全面的Python图谱,直接分享给你们!!!(我看过,知识点还是很全面的,基础知识.数据分析.爬虫实战.后台开发实战以及人工智能实战项目,都包含了 ...

  8. 杭州python就业情况_杭州Python就业前景如何 企业常问的Python面试题有哪些

    人工智能时代的来临带动了Python的火爆,企业对Python人才需求迫切,选择学习Python的Python的人与日俱增.有人好奇杭州Python就业前景如何,有人想知道企业常问的Python面试题 ...

  9. 【python热搜爬虫+定时发送邮件操作①】不会吧不会吧!不会2020了还有人需要用软件看微博热搜吧?

    以下内容为本人原创,欢迎大家观看学习,禁止用于商业用途,转载请说明出处,谢谢合作! ·作者:@Yhen ·原文网站:CSDN ·原文链接:https://blog.csdn.net/Yhen1/art ...

最新文章

  1. 人类首次商业太空行走敲定!马斯克SpaceX宣布新一轮太空旅行计划,美国富豪成回头客...
  2. 剑指offer 算法 (递归与循环)
  3. Attention的梳理、随想与尝试
  4. 表格过滤器_记录和管理零散信息,什么软件比 Excel 表格更方便
  5. sqlite3修改表内容python_python之sqlite3使用详解(转载)
  6. Ionic Cordova 环境配置window
  7. ef 执行mysql语句_在EF中执行SQL语句
  8. 在Docker官网上浏览版本号
  9. 如何在Windows下搭建Android开发环境
  10. c语言case用多重语句,switch多重选择
  11. 2021牛客多校10 F-Train Wreck(思维,贪心,堆)
  12. 基于北洋PT站表结构分析以及ORM重写
  13. The projects in the reactor contain a cyclic reference
  14. 再谈宋星博客的留言与seo培训联盟
  15. 汉化版PHP代码审计工具rips
  16. 2018入门级手机VR眼镜对比区别:ugp vr眼镜怎么样?目前哪个vr眼镜牌子效果更好,vr眼镜选哪款?
  17. SSSP整合分页CRUD
  18. Python-爬虫-requests库用语post登录
  19. 调用方法[manageApp]时发生异常 java.lang.IllegalStateException: 启动子级时出错
  20. java基础-常用快捷键及基本dos命令

热门文章

  1. CentOS 6.5安装MongoDB 2.6(多yum数据源)
  2. glCullFace,GL_CULL_FACE
  3. 一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-基于接口驱动的数据层...
  4. 用python画皮卡丘源代码-实现童年宝可梦,教你用Python画一只属于自己的皮卡丘...
  5. python open 打开是什么类型的文件-详解Python中open()函数指定文件打开方式的用法...
  6. 计算机科学与技术python方向是什么意思-大学计算机科学与技术相关专业学习路线...
  7. python小课骗局-Python小课怎么样啊?
  8. python网络爬虫的基本步骤-Python网络爬虫学习手记(1)——爬虫基础
  9. python版本越高越好吗-5个Python特性 越早知道越好的
  10. python该怎么自学-Python 应该怎么学?