c/perl/python 中简单程序之间的执行时间过长的原因是什么?

Ste*_*ieD 1 c python perl execution

我用 C、Perl 和 Python 编写了一个简单的程序,它递增一个变量,直到它达到 10 亿。我没想到不同语言之间会有太大差异,但看到巨大差异感到非常惊讶。这些程序简单地数到 10 亿:

在 c:

int main() {
  int c = 0;

  while (c < 1000000000) {
    c++;
  }
}
Run Code Online (Sandbox Code Playgroud)

在 Perl 中:

#! /usr/bin/env perl

use strict;
use warnings;

my $x = 0;

while ($x < 1000000000) {
  $x++;
}
Run Code Online (Sandbox Code Playgroud)

在 Python 中:

#!/usr/bin/env python

i = 0
while i < 1000000000:
  i += 1
Run Code Online (Sandbox Code Playgroud)

使用 zsh/bash 时间函数的运行时间是:

对于 c: 1.78s 用户 0.01s 系统 98% cpu 1.813 总计

对于 perl:29.86s 用户 0.13s 系统 99% cpu 30.205 总计

对于 Python:71.96s 用户 0.32s 系统 98% cpu 1:13.16 总计

我很难相信 c 比 perl 快 15 倍,比 Python 快约 35 倍。对于这样一个简单的程序来说,这似乎很疯狂?为什么差别这么大?

Dav*_*ell 5

由于 perl 变量是无类型的(并且实际上可以在执行过程中改变它们的有效类型),对它们的每个操作(例如 < 和 ++)都必须检查:这是一个绑定变量吗?这是一个重载的值吗?这是一个整数吗?或浮标;或一个字符串:如果是这样,它是否具有有效的数字解释;还是未定义?等等。对于像 < 这样的二进制操作,该逻辑适用于两个 args,并且 args 的类型可以不同。所以 perl 必须处理添加到浮点数等的整数。

此外,perl 不限制算术运算的结果为 int。相反,它动态更新变量的类型,例如从有符号整数到无符号整数到双精度,以最好地保留结果的值和准确性。

这意味着 perl 必须做大量的工作,例如一个简单的加法:与 C 相比,编译器知道两个 args 都是有符号整数,并且不关心结果是否溢出;并且可以将加法映射到单个 CPU 加法指令