[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends] Javaベンチマーク
ベンチマークを行なった時の結果です。
当時、雑誌とかを見ると、JavaはCに比べてだいたい15〜20倍ぐら
い遅い、となっていたので、本当かなあ、と思い試してみたのでした。
今なら、JITとかもありますし、また違う結果になると思いますが...
# 誰か計測してみませんか?
問題は以下の通りです。
「ビリヤードの玉(1〜15)を5個ネックレスのように輪にして繋ぐ。
そこから隣同士連続したものならいくつ取っても良いとして、取っ
た玉の数字の合計で 1〜21までの数ができるようにするためには、
何番の玉をどのように繋げばよいか?」
# 某推理小説に出ていた問題です (^^;
この問題を力技で解くとすると(もちろんよりエレガントで、人力
で解ける方法があるのですが)、
・15個の玉から5個の玉を取り出すので、その順列のパターンは
15! / (15 - 5)! = 360360
・その中から連続する玉を取り出す組合せは、開始点が5通りで玉
の数が1〜5の 25通り。
これを掛け算したパターンだけ検証すれば良いことになります。ネッ
クレスなので循環と裏返しを省けば 1/10 になりますけど、今回そ
れは考えてません(よって解は10個出る)。
計測結果
1) Cの場合(-Oオプション付き)
3.0u 0.0s 0:08 33% 0+0k 0+0io 0pf+0w
2) Java ヒープ動的使用時(-Oオプション付き)
ひとつの順列の作成終了後、連続する玉を取り出すための配列(要
素数5)が必要ですが、それを毎回(360360回)ヒープにとる方式。
Javaのプログラミングでは、通常こちらのスタイルになるのではな
いかと思います。
130.0u 0.0s 2:55 74% 0+0k 0+0io 0pf+0w
3) Java ヒープ静的使用時(-Oオプション付き)
連続する玉を取り出すための配列を最初に一回だけヒープに取る方
式。本来ローカル変数にすべきものがクラスに行っちゃうんで美し
くない。
126.0u 0.0s 2:08 97% 0+0k 0+0io 0pf+0w
どこが 20倍やねん。
しかし、2)と3)の所要時間がそれほど変わらないのは驚きです。
以下、Javaプログラムのソースです(ヒープ動的確保版)。
実行していることがわかるように、順列を1000個チェックする毎に
"*"を表示しています。C の方は配列をグローバルに取っている以
外、だいたい同じものです。
# ベースのソースはCですし、VMの性能試験ですからCと条件を同じ
# にしなければならないわけで、staticの固まりになっています。
# OOPしてないぞ、と文句を付けないように(^^;
<ここから><ここから><ここから><ここから><ここから><ここから>
class Ball {
static int [] pattern;
static boolean [] used;
static int count;
public static void main (String args[]) {
pattern = new int [5];
used = new boolean [16];
count = 0;
clearUsed();
makePattern(0);
}
static void clearUsed() {
int i;
for (i = 0; i <= 15; i++) {
used[i] = false;
}
}
static void checkPattern() {
int start, len;
int i, pos;
int sum;
boolean [] check;
check = new boolean [100];
for (i = 1; i <= 21; i++) {
check[i] = false;
}
for (start = 0; start < 5; start++) {
for (len = 1; len <= 5; len++) {
sum = 0;
pos = start;
for (i = 0; i < len; i++) {
sum += pattern[pos];
if (pos < 4) {
pos++;
} else {
pos = 0;
}
}
check[sum] = true;
}
}
for (i = 1; i <= 21; i++) {
if (check[i] == false)
break;
}
if (i == 22) {
System.out.print("\n");
for (i = 0; i < 5; i++) {
System.out.print(pattern[i]);
}
System.out.print("\n");
}
count++;
if (count % 1000 == 0)
System.out.print("*");
}
static void makePattern(int depth) {
int i;
for (i = 1; i <= 15; i++) {
if (!used[i]) {
pattern[depth] = i;
used[i] = true;
if (depth < 4) {
makePattern(depth + 1);
} else {
checkPattern();
}
used[i] = false;
}
}
}
}
<ここまで><ここまで><ここまで><ここまで><ここまで><ここまで>
------------------------------------------------------------
前橋 和弥 maebashi@xxxxxxxxxx
中部ソフトエンジニアリング(株)
〒450 名古屋市中村区名駅4-10-25(名駅IMAIビル 5F)
Tel:(052)583-4511(代) 内線 252 Fax:(052)583-4566
------------------------------------------------------------