概要
単純な繰り返しで、数学的な計算のみのパフォーマンスですが、プログラミング言語も日々精進してそうなので、次のようなもののパフォーマンスを計ってみました。
対象となる言語は
- PHP
- Ruby
- Jruby
- Java
- Groovy
- C
です。
詳細
そして、どんなパフォーマンスを計ったかというと
- 1~nまで順繰りに
- その数まで1から順に足していって
- その数までの和をそれぞれn個の配列1つずつに格納し
- 最後の配列の答えをを標準出力する
- 1のnは10000と100000の2つを使い、かかった時間をミリ秒で計測する。
というもの。つまり、nが5なら
- 0番目の配列:1
- 1番目の配列:1 + 2 = 3
- 2番目の配列:1 + 2 + 3 = 6
- 3番目の配列:1 + 2 + 3 + 4 = 10
- 4番目の配列:1 + 2 + 3 + 4 + 5 = 15
とそれぞれ計算し、配列に格納し、最後の15を標準出力するプログラムで、nが5ではなく、1万と10万で計測するということになります。
それから、いくつかポイントがあるので列挙します。
- OS:Windows7 CPU:Corei-7-4790 @3.6GHz Memory: 32G
- 1のOS上に載ったVirutalBox4.3.20 OS:Ubuntu CPU:core4 Memory: 7068M
- 上記の1と2が立ち上がった状態で、1はDosプロンプト、2ではbash上で計測
- 1ではelapsedtimeを使い、2ではtimeを使って計測
- Cではコンパイルオプションに「-O3」を使う
- 100000回では、桁があふれるのlongを利用している(そうしないと答えが合わない)
- Ruby等にいわゆる for(int i = 1;i <= n; i++) というのがないので、ループはwhileを利用
- WindowsにおけるCはmingwの32ビット版、Ubuntu(64ビット版)は通常のGCC
- Groovyは「@CompileStatic」を付けたものがめっちゃ速いので、つけたのと付けていないのを測定
- 測定は4回行い、1回目のデータは破棄し、2回~4回の平均値を取る
- ソースはこのページの最後にある
若干の考察(結果はこの下)
- Java系をのぞき、全てなぜかVirtualBoxの方が速い(Ruby、PHP、C)。Cはmingwのwin32だからかも、という理由はありそうなんですが、それ以外はどちらも64ビットを使っているはず。不思議です。VirtualBoxが優秀なのか、Ubuntuが優秀なのか・・・?
- JrubyがほぼCRubyぐらいの速さになっている(少ない処理では若干遅くなっていますが)。むしろ、10万回の方のように、CRubyより速い! ※jrubycでコンパイルするともっと速くなるようなことが書いてありましたが、ほぼ10000回も100000回も同じでした。JITが優秀ということ?
- Groovyは、ソースに@CompileStaticを付けると、JavaのNativeと同じくらい速くなるのには驚きました。この辺、Jrubyに対して優位な感じがします。
- 結果にはありませんが、for文で最初やっていたのですが、その時はPHPの方がRubyよりも速かったのですが、whileだと逆転しています。
- JavaとCは、ほぼ互角な感じですね。
- Rubyは2.1になってから速くなったと聞きますが、本当にそのような印象です。
- もちろん、この結果から、単純に一般化するのは難しいと思います。DBやら、ネット環境などパフォーマンスを決める要因は様々です。ただ、ちょっとは目安になるかも、という程度しょうかw
結果
Version等
Windows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
C:\work>php -v
PHP 5.6.3 (cli) (built: Nov 12 2014 17:18:08)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
C:\work>ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [i386-mingw32]
C:\work>jruby -v
jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on Java HotSpot(TM) 64-Bit Server
VM 1.8.0_20-b26 +jit [Windows 7-amd64]
C:\work>java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
C:\work>gcc -v
....
Target: i686-w64-mingw32
Configured with: ....
gcc version 4.7.2 (rubenvb-4.7.2-release)
C:\work>groovy -v
Groovy Version: 2.3.8 JVM: 1.8.0_20 Vendor: Oracle Corporation OS: Windows 7
Linux(Ubuntu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
chikkun@chikkun-VirtualBox:~$ php -v
PHP 5.5.15 (cli) (built: Aug 20 2014 13:51:55)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
chikkun@chikkun-VirtualBox:~$ ruby -v
jruby 1.7.18 (1.9.3p551) 2014-12-22 625381c on Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17 +jit [linux-amd64]
chikkun@chikkun-VirtualBox:~$ jruby -v
jruby 1.7.18 (1.9.3p551) 2014-12-22 625381c on Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17 +jit [linux-amd64]
chikkun@chikkun-VirtualBox:~$ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
chikkun@chikkun-VirtualBox:~$ groovy -v
Groovy Version: 2.4.0-rc-1 JVM: 1.8.0_25 Vendor: Oracle Corporation OS: Linux
chikkun@chikkun-VirtualBox:~$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ソース
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
define('N',10000);
function sumup($n){
$sum = 0;
$i = 1;
while($i <= $n){
$sum += $i;
$i += 1;
}
return $sum;
}
function main(){
$result = array();
echo "start\n";
$count = 1;
while($count <= N){
$result[$count - 1] = sumup($count);
$count += 1;
}
echo "end\n";
echo $result[N - 1] . "\n";
}
main();
?>
Ruby, Jruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
N = 100000
def sumup(n)
sum = 0
i = 1
while(i <= n)
sum += i
i += 1
end
sum
end
def main()
result = []
puts "start"
count = 1
while(count <= N)
result[count -1] = sumup(count)
count += 1
end
puts "end"
puts result[-1]
end
main()
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class PTest {
static int N = 100000;
static Long sumup(int n){
long sum = 0L;
int i = 1;
while(i <= n){
sum += i;
i += 1;
}
return sum;
}
public static void main(String[] args){
Long[] result = new Long[N];
System.out.println("start");
int count = 1;
while(count <= N){
result[count -1] = sumup(count);
count += 1;
}
System.out.println("end");
System.out.println(result[N - 1]);
}
}
Groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def sumup(int n){
def long sum = 0
int i = 1
while(i <= n){
sum += i
i += 1
}
return sum
}
def main(){
int N = 100000
long[] result = new long[N]
println "start"
def count = 1
while(count <= N){
result[count -1] = sumup(count)
count += 1
}
println "end"
println result[N - 1]
}
main()
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#define N 100000
long long sumup(int n) {
int i = 1;
unsigned long long sum = 0;
while(i <= n) {
sum += i;
i++;
}
return sum;
}
int main() {
int count = 1;
unsigned long long result[N];
printf("start\n");
while (count <= N) {
result[count - 1] = sumup(count);
count++;
}
printf("end\n");
printf("%lld", result[N - 1]);
return 0;
}