为什么这个perl脚本运行的方式比它慢是C语言的? [英] Why does this perl script run way slower than it's c counterpart?

查看:164
本文介绍了为什么这个perl脚本运行的方式比它慢是C语言的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解决在perl 的琐碎spoj问题。所以,我想出了这个解决方案:

I was solving this trivial spoj problem in perl. So I came up with this solution:

while ("0 0 0\n" ne ($string = <STDIN>)) {
  my @a = split ' ', $string;
  $a1 = $a[0];
  $a2 = $a[1];
  $a3 = $a[2];

  if($a2 - $a1 == $a3 - $a2) {
    $c  = $a2 - $a1;
    $a4 = $a3 + $c;
    print("AP ", $a4);
  }
  else {
    $c  = $a2 / $a1;
    $a4 = $a3 * $c;
    print("GP ", $a4);
  }

  print "\n";
}

要我吃惊的是,它超过了时间限制。

To my surprise, it exceeded the time limit. When I tried the same thing in C, it run successfully with a minimal run time.Here is the C version:

#include <stdio.h>

int main()
{
  int a1, a2, a3, a4, c;
  while (1) {
    scanf("%d %d %d", &a1, &a2, &a3);
    if (a1 == 0 && a2 == 0 && a3 == 0) break;
    if (a2 - a1 == a3 - a2) {
      c  = a2 - a1;
      a4 = a3 + c;
      printf("AP %d\n", a4);
    }
    else {
      c  = a2 / a1;
      a4 = a3 * c;
      printf("GP %d\n", a4);
    }
  }
  return 0;
}

所以,请你告诉我:

So, could you please tell me:

时的Perl真的那么多(200X至少),当谈到这个问题比C慢?我怀疑它与输入和高层次的结构,如使用数组做,或者没有在我的code导致程序拖延的错误。

Is perl really that much (200x at least) slower than C when it comes to this problem? I suspect it has to do with the input and the high level structures such as arrays used, or maybe there is a bug in my code causing the program to stall.

推荐答案

有各种事情不对您的基准:

There are various things wrong with your benchmark:


  • 程序不完全等价的。

  • 在至少你的Perl code是unidiomatic(你甚至不声明所有的变量!)

但最重要的:


  • 这个基准是基于IO。

  • 如果输入并不大,启动时间也有关。

你做的计算是绝对便宜,最贵的部分是阅读和扫描输入。它是没有惊喜的最小的C会更快这里比更高级别PerlIO的系统

The calculations you do are absolutely cheap, the most expensive part is reading and scanning for input. It is no suprise that the minimal C will be faster here than the higher-level PerlIO system.

你不知道的另一件事是Perl是一种的间preTED语言的,而C被通常编译。在Perl的情况下,实际上是一个C程序,看起来在某些数据结构(运codeS),并根据某些标志确实加法,乘法,分支,或比较。 Perl变量是标量,这实际上是一个 SV * - 一个指向SV结构。这些结构是不是 INT 大得多。每一个Perl程序被执行时, perl的间preTER解析和时间编译整个源代码code到运codeS。

Another thing you don't realize is that Perl is an interpreted language, whereas C is usually compiled. In the case of Perl, there is actually a C program that looks at certain data structures (opcodes) and depending on certain flags does addition, multiplication, branching, or comparision. Perl variables are scalars, which are actually an SV* - a pointer to an SV struct. These structs are considerably larger than an int. Each time a Perl program is executed, the perl interpreter parses and compiles the whole source code to the opcodes.

C,另一方面,编译成机器code比运算codeS更有效。这是提前执行完成的,这样的编译时间不计入这一基准。启动将为此更快。 C能进行优化,使用的寄存器,而不是在堆中,这使得简单的数据结构,如 INT 取值更快的位置。 IO系统在C标准库是更为裸机较复杂的系统Perl有(解码层,缓冲)。总而言之,C有迂回的水平少比Perl。

C, on the other hand, compiles to machine code which is more efficient than opcodes. This is done ahead of execution, so that compilation time is not factored into this benchmark. Startup will be faster for this reason. C can be optimized to use registers instead of locations on the heap, which makes simple data structures like ints much faster. The IO system in the C standard library is far more bare-bones than the complex system Perl has (decoding layers, buffering). All in all, C has fewer levels of indirections than Perl.

由于Perl是一个C程序,迂回的这些层面做出的Perl〜100×慢。差距扩大的数学重基准(SV比整数更贵),但对于字符串操作更接近像首页和正则表达式。

Because perl is a C program, these levels of indirections make Perl ~100× slower. The gap widens for math-heavy benchmarks (SV is more expensive than ints), but is closer for string operations like index and regexes.

有关记录,这里是你的Perl code的惯用版本。不,它不会运行得更快。

For the record, here is a idiomatic version of your Perl code. No, it won't run faster.

while (<>) {
  last if $_ eq "0 0 0\n";
  my ($a1, $a2, $a3) = split;

  if($a2 - $a1 == $a3 - $a2) {
    my $a4 = $a3 + $a2 - $a1;
    print "AP $a4\n";
  }
  else {
    my $a4 = $a3 * $a2 / $a1;
    print "GP $a4\n";
  }
}

这篇关于为什么这个perl脚本运行的方式比它慢是C语言的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆