node与c java_node.js如何比C和Java更快?比较node.js,c,java和python的基准

我做了一个非常简单的基准测试程序,该程序可以使用4种不同的语言计算出高达10,000,000的所有素数。

(2.97秒)-node.js(javascript)(4.4.5)

(6.96秒)-c(c99)

(6.91秒)-Java(1.7)

(45.5秒)-python(2.7)

以上平均每次运行3次,用户时间

Node.js到目前为止运行最快。这使我感到困惑,原因有两个:

在这种情况下,c和java使用(长)整数时,javascript始终对变量使用双精度浮点数。整数数学应该更快。

实际上,JavaScript是一种及时编译的语言,通常被称为解释型。但是即使如此,JIT编译器又如何比完全编译的语言更快呢?python代码运行最慢,这不足为奇,但是为什么node.js代码没有以与python相似的速度运行?

我使用-O2优化来编译c代码,但是我在所有优化级别上都进行了尝试,但是并没有明显的区别。

countPrime.js

"use strict";

var isPrime = function(n){

//if (n !== parseInt(n,10)) {return false};

if (n < 2) {return false};

if (n === 2) {return true};

if (n === 3) {return true};

if (n % 2 === 0) {return false};

if (n % 3 === 0) {return false};

if (n % 1) {return false};

var sqrtOfN = Math.sqrt(n);

for (var i = 5; i <= sqrtOfN; i += 6){

if (n % i === 0) {return false}

if (n % (i + 2) === 0) {return false}

}

return true;

};

var countPrime = function(){

var count = 0;

for (let i = 1; i < 10000000;i++){

if (isPrime(i)){

count++;

}

}

console.log('total',count);

};

countPrime();

node.js结果

$ time node primeCalc.js

total 664579

real 0m2.965s

user 0m2.928s

sys 0m0.016s

$ node --version

v4.4.5

primeCalc.c

#include

#include

#define true 1

#define false 0

int isPrime (register long n){

if (n < 2) return false;

if (n == 2) return true;

if (n == 3) return true;

if (n % 2 == 0) return false;

if (n % 3 == 0) return false;

if (n % 1) return false;

double sqrtOfN = sqrt(n);

for (long i = 5; i <= sqrtOfN; i += 6){

if (n % i == 0) return false;

if (n % (i + 2) == 0) return false;

}

return true;

};

int main(int argc, const char * argv[]) {

register long count = 0;

for (register long i = 0; i < 10000000; i++){

if (isPrime(i)){

count++;

}

}

printf("total %li\n",count);

return 0;

}

c结果

$ gcc primeCalc.c -lm -g -O2 -std=c99 -Wall

$ time ./a.out

total 664579

real 0m6.718s

user 0m6.668s

sys 0m0.008s

PrimeCalc.java

公共类PrimeCalc {

public static void main(String[] args) {

long count = 0;

for (long i = 0; i < 10000000; i++){

if (isPrime(i)){

count++;

}

}

System.out.println("total "+count);

}

public static boolean isPrime(long n) {

if (n < 2) return false;

if (n == 2) return true;

if (n == 3) return true;

if (n % 2 == 0) return false;

if (n % 3 == 0) return false;

if (n % 1 > 0) return false;

double sqrtOfN = Math.sqrt(n);

for (long i = 5; i <= sqrtOfN; i += 6){

if (n % i == 0) return false;

if (n % (i + 2) == 0) return false;

}

return true;

};

}

Java结果

$ javac PrimeCalc.java

$ time java PrimeCalc

total 664579

real 0m7.197s

user 0m7.036s

sys 0m0.040s

$ java -version

java version "1.7.0_111"

OpenJDK Runtime Environment (IcedTea 2.6.7) (7u111-2.6.7-0ubuntu0.14.04.3)

OpenJDK 64-Bit Server VM (build 24.111-b01, mixed mode)

primeCalc.py

import math

def isPrime (n):

if n < 2 : return False

if n == 2 : return True

if n == 3 : return True

if n % 2 == 0 : return False

if n % 3 == 0 : return False

if n % 1 >0 : return False

sqrtOfN = int(math.sqrt(n)) + 1

for i in xrange (5, sqrtOfN, 6):

if n % i == 0 : return False;

if n % (i + 2) == 0 : return False;

return True

count = 0;

for i in xrange(10000000) :

if isPrime(i) :

count+=1

print "total ",count

python结果

time python primeCalc.py

total 664579

real 0m46.588s

user 0m45.732s

sys 0m0.156s

$ python --version

Python 2.7.6

linux

$ uname -a

Linux hoarfrost-node_6-3667558 4.2.0-c9 #1 SMP Wed Sep 30 16:14:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

额外的c运行时间(附录)

(7.81 s)没有优化,gcc primeCalc.c -lm -std = c99 -Wall

(8.13 s)优化0,gcc primeCalc.c -lm -O0 -std = c99 -Wall

(7.30 s)优化1,gcc primeCalc.c -lm -O1 -std = c99 -Wall

(6.66 s)优化2,gcc primeCalc.c -lm -O2 -std = c99 -Wall

每个优化级别用户时间平均3次新运行*

这段代码使用的示例实际上并没有做任何重要的事情。好像编译器可以在编译时算出结果,甚至不需要执行100000000次循环就可以得出答案。如果将另一除法步骤添加到计算中,则优化的意义将大大降低。

for (long i = 0; i < 100000000; i++) {

d += i >> 1;

d = d / (i +1); //

}

(1.88秒)无优化

(1.53秒),具有优化(-O2)

更新 03/15/2017从@leon阅读答案后,我进行了一些验证测试。

测试1至32位Beaglebone Black,664,579装填至10,000,000

未经编辑的calcPrime.js和calcPrime.c在具有32位处理器的Beaglebone黑色上运行。

C代码= 62秒(gcc,长数据类型)

JS代码= 102秒(节点v4)

测试2-64位Macbook Pro,664,579灌注10,000,000

用uint32_t替换calcPrime.c代码中的长数据类型,并在具有64位处理器的MacBook Pro上运行。

C代码= 5.73秒(c,长数据类型)

C代码= 2.43秒(clang,uint_32_t数据类型)

JS代码= 2.12秒(节点v4)

测试3-64位Macbook Pro,91,836个素数(i = 1; i <8,000,000,000; i + = 10000)

在C代码中使用无符号的长数据类型,强制javascript使用64位。-C代码= 20.4秒(clang,长数据类型)-JS代码= 17.8秒(节点v4)

测试4-64位Macbook Pro,86,277个素数(i = 8,000,00,001; i <16,000,000,000; i + =

10000)

在C代码中使用无符号的长数据类型,强制javascript使用所有64位。-C代码= 35.8秒(c,长数据类型)-JS代码= 34.1秒(节点v4)

测试5-Cloud9 64位Linux,(i = 0; i <10000000; i ++)

language datatype time % to C

javascript auto 3.22 31%

C long 7.95 224%

C int 2.46 0%

Java long 8.08 229%

Java int 2.15 -12%

Python auto 48.43 1872%

Pypy auto 9.51 287%

测试6-Cloud9 64位Linux,(i = 8000000001; i <16000000000; i + = 10000)

javascript auto 52.38 12%

C long 46.80 0%

Java long 49.70 6%

Python auto 268.47 474%

Pypy auto 56.55 21%

(所有结果均为三个运行的平均用户秒数,运行之间的时间差异<10%)

混合结果

在整数范围内将C和Java数据类型更改为整数会大大加快执行速度。在BBB和Cloud9计算机上,切换到int使得C比node.js更快。但是在我的Mac上,node.js程序仍然运行得更快。也许是因为Mac使用的是clang,而BBB和Cloud

9计算机使用的是gcc。有谁知道gcc的编译程序是否比gcc快?

当使用所有64位整数时,C在BBB和Cloud9 PC上比node.js快一点,但在我的MAC上慢一点。

在这些测试中,您还可以看到pypy的速度大约是标准python的四倍。

node.js甚至与C兼容的事实令我惊讶。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值