首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么一个包含100亿次迭代的大型for循环在Python中运行的时间要比在C中长得多?

问为什么一个包含100亿次迭代的大型for循环在Python中运行的时间要比在C中长得多?
EN

Stack Overflow用户
提问于 2018-09-29 16:12:46
回答 3查看 7.7K关注 0票数 9

我目前正在比较Python3和C中的两个循环计算,对于Python,我有:

代码语言:javascript
复制
# Python3
t1 = time.process_time()
a = 100234555
b = 22333335
c = 341500
for i in range(1, 10000000001):
    a = a - (b % 2)
    b = b - (c % 2)
print("Sum is", a+b)
t2 = time.process_time()
print(t2-t1, "Seconds")

在C语言中,我也做了同样的事情:

代码语言:javascript
复制
#include <stdio.h>

int main() {
   long long a = 100234555;
   long long b = 22333335;  
   long long c = 341500;
   for(long long i = 1; i <= 10000000000; i++){
        a = a - (b % 2);
        b = b - (c % 2);
   }
   printf("Sum is %lld\n", a+b);
   return 0;
}

我在Python和C中对代码进行了计时,Python的计时大约为3500秒,而C(包括编译和执行)的计时时间仅为0.3秒。

我想知道为什么时间上有这么大的差别。执行是在具有100 GB Ram和足够处理能力的服务器上完成的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-29 16:20:40

这部分是因为Python字节码是由程序而不是直接由CPU执行的,但是大部分开销是由不可变的整数所引起的内存分配和去分配造成的,这是由于对象模型,而不是解释。

您的C代码可以更改数字的值,但在Python中,数字是不可变的,这意味着它们不会改变。这意味着当您完成和时,Python必须为每个新值创建一个新的int对象,然后在旧的int不再使用后销毁它们。这使得它比仅仅修改单个内存值要慢得多。

还有一种可能性,即您的C编译器是聪明的,以及通过一系列优化可以完全删除for循环的原因,结果将是相同的--就好像循环已经实际运行了一样。如果在您的示例中是这样的话,我希望代码的运行速度会比它快得多,但它可以做到这一点。

Python没有这样聪明的编译器。它不能做到这样的伟大和聪明的事情;它只是不是为了优化代码而设计的,因为在动态类型语言中这样做是很困难的(尽管Python是强类型的,这在某种程度上是有可能的)。

票数 19
EN

Stack Overflow用户

发布于 2018-09-29 21:43:51

正如dmuir所注意到的,如果编译器正确地传播了一些常量,代码就可以大大简化。例如:clang -O1将C代码编译到下面(cf https://gcc.godbolt.org/z/1ZH8Rm ):

代码语言:javascript
复制
main:                                   # @main
        push    rax
        movabs  rsi, -9877432110
        mov     edi, offset .L.str
        xor     eax, eax
        call    printf
        xor     eax, eax
        pop     rcx
        ret
.L.str:
        .asciz  "Sum is %lld\n"

gcc -O1产生本质上类似的代码。

由于这归结为对printf的单个调用,因此解释如下:

  • Python编译器在优化这段代码方面不如C编译器聪明。
  • 您的C编译器需要很长时间来编译这12行代码。考虑到硬件设置,3秒太长了!在我的小型笔记本电脑上,编译和运行所有优化的代码只需0.15秒。您正在编译为C++吗?

使用禁用的优化(-O0)测试C版本会产生以下输出:

代码语言:javascript
复制
$ time (clang -O0 -o loop10g loop10g.c && ./loop10g)
Sum is -9877432110

real    4m15.352s
user    3m47.232s
sys     0m3.252s

使用未优化的C仍然比Python快得多: 255秒vs:>3500

Python代码使用字节代码和具有动态类型值的堆栈进行解释: 10到20的因子是典型的减速。此外,对于大值,整数算法会自动切换到bignum模式,这可能是这里的情况,尽管代价应该更高。

票数 10
EN

Stack Overflow用户

发布于 2018-09-29 16:16:26

答案很简单。Python是一种解释语言。所有指令都由解释器(执行脚本的特殊程序)执行。它比编译成本机代码的C代码慢得多。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52570192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档