MacBook Pro (15-inch, 2017)上に構築したVagrant環境でチェック。
CPU: i7-7820HQ CPU @ 2.90GHz
MEM: 985MiB
OS: Ubuntu 18.04.3 LTS x86_64
Kernel: 4.15.0-62-generic
Rust 1.36.0
$ time ./leibniz
3.141592643589326
real 0m3.842s
user 0m3.835s
sys 0m0.005s
コード
leibniz.rs
fn main() {
let mut ans = 0.0;
let to = 1e8 as usize;
for i in 0..to {
ans += (-1.0 as f64).powf(i as f64) / ((2.0 * (i as f64) + 1.0));
}
println!("{}", ans * 4.0_f64);
}
Java11+OpenJ9
$ time java Leibniz
3.141592663589326
real 0m1.438s
user 0m1.518s
sys 0m0.059s
コード
Leibniz.java
public class Leibniz {
public static void main(String[] args) {
var ans = 0.0;
for(var i = 0; i <= 1e8; i++) {
ans += Math.pow(-1, i) / (2 * i + 1);
}
System.out.println(ans * 4);
}
}
Ruby 2.6.4p104
$ time ruby leibniz.rb
3.141592663589326
real 0m15.551s
user 0m15.509s
sys 0m0.037s
コード
leibniz.rb
ans = 0;
(1e8 + 1).to_i.times do |i|
ans += ((-1.0)**i) / (2.0 * i.to_f + 1.0)
end
puts ans * 4
Node v12.10.0
$ time node leibniz.js
3.141592643589326
real 0m0.943s
user 0m0.916s
sys 0m0.025s
コード
leibniz.js
let ans = 0;
for(let i = 0; i < 1e8; i++) {
ans += Math.pow(-1, i) / ((2 * i) + 1);
}
console.log(ans * 4);
PHP 7.2.19-0ubuntu0.18.04.2
$ time php leibniz.php
3.1415926635893
real 0m11.439s
user 0m11.423s
sys 0m0.013s
コード
leibniz.php
<?php
$ans = 0;
for($i = 0; $i <= 1e8; $i++) {
$ans += (-1) ** $i / (2 * $i + 1);
}
echo $ans * 4 . PHP_EOL;
C (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1))
$ time ./leibniz-with-pow
3.141593
real 0m4.037s
user 0m4.037s
sys 0m0.000s
コード
leibniz.c
#include <stdio.h>
#include <math.h>
int main()
{
double ans = 0.0;
for (int i = 0; i <= (int)1e8; i++)
{
ans += pow(-1, i) / (2 * i + 1);
}
printf("%f\n", ans * 4);
return 0;
}
まとめ
Node < Java < Rust < C < PHP < Ruby
となった。かなり意外。コード何か違うんかな。。
なお以下のように pow
を使わないでやると早くなる。と思ったけど、Ruby早くならない...
どうなってんだろう?
leibniz2.rs
fn main() {
let mut ans = 0.0;
let to = 1e8 as usize;
for i in 0..to {
let p = if i % 2 == 0 {
1
} else {
-1
};
ans += (p as f64) / ((2.0 * (i as f64) + 1.0));
}
println!("{}", ans * 4.0_f64);
}
/**
$ time ./leibniz2
3.141592643589326
real 0m0.141s
user 0m0.136s
sys 0m0.004s
**/
Leibniz2.java
public class Leibniz2 {
public static void main(String[] args) {
var ans = 0.0;
for(var i = 0; i <= 1e8; i++) {
double p = 0.0;
if(i % 2 == 0) {
p = 1;
} else {
p = -1;
}
ans += p / (2 * i + 1);
}
System.out.println(ans * 4);
}
}
/**
$ time java Leibniz2
3.141592663589326
real 0m0.750s
user 0m0.762s
sys 0m0.046s
**/
leibniz2.rb
ans = 0;
(1e8 + 1).to_i.times do |i|
p = (i % 2 == 0) ? 1 : -1
ans += p / (2.0 * i.to_f + 1.0)
end
puts ans * 4
# $ time ruby leibniz2.rb
# 3.141592663589326
# real 0m13.671s
# user 0m13.632s
# sys 0m0.034s
leibniz2.js
let ans = 0;
for(let i = 0; i < 1e8; i++) {
const p = i % 2 === 0 ? 1 : -1;
ans += p / ((2 * i) + 1);
}
console.log(ans * 4);
/**
$ time node leibniz2.js
3.141592643589326
real 0m0.268s
user 0m0.258s
sys 0m0.010s
**/
leibniz2.php
$ans = 0;
for($i = 0; $i <= 1e8; $i++) {
$p = $i % 2 === 0 ? 1 : -1;
$ans += $p / (2 * $i + 1);
}
echo $ans * 4 . PHP_EOL;
/* *
$ time php leibniz2.php
3.1415926635893
real 0m5.287s
user 0m5.285s
sys 0m0.000s
* */
leibniz2.c
#include <stdio.h>
int main()
{
double ans = 0.0;
for (int i = 0; i <= (int)1e8; i++)
{
double p;
if(i % 2 == 0) {
p = 1.0;
} else {
p = -1.0;
}
ans += p / (2 * i + 1);
}
printf("%f\n", ans * 4);
return 0;
}
/**
$ time ./leibniz2
3.141593
real 0m0.280s
user 0m0.275s
sys 0m0.005s
**/
pow
使うと遅くなるんだなぁ。
というかNode早すぎじゃない?