Help us understand the problem. What is going on with this article?

ライプニッツの公式で言語速度チェック

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早すぎじゃない?

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away