C++, C#, Javascript, Pythonの実行速度を比較してみました。（2021年版）


# はじめに
はじめまして、ハーツテクノロジーの山口です。

今回はC++やC#など各言語の理解を深めるために、同僚のJamesさんが2019年に書いた記事[[2019年の後半。いま、高速で生産性の高い開発言語はなに？！旬の言語 C++, C#, Javascript, Python で比較してみた！]](https://qiita.com/james0827/items/b69fd64a16d66cbe9327)を2021年12月の環境で比較をしました。

# 実行環境
- CPU: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz   2.30 GHz
- RAM: 16.0 GB (15.8 GB 使用可能)
- OS : Windows 10 Pro

今回比較対象としたのは以下の言語です。

- C++ / MinGW(v8.1.0)
- C# / Visual Studio 2022
- Javascript / node.js(v16.13.1)
- Python / Python(v3.8.2)

C++には最適化オプションを付けて実行しています。

# コードについて
参考にした記事と同じく、ライプニッツの公式を使用し円周率を求めます。ライプニッツの公式は以下の通りに表されます。
![Leibniz .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/de6cf696-5e05-a09a-e5a2-661d3daee00a.png)
今回は実行速度を比べるためシンプルにdoubleで計算するコードを書き計測しました。

## C++
``` cpp
#include <stdio.h>
#include <time.h>

int main()
{
    printf( "start\n" );
    
    double limit = 10;
    for (int i = 0; i < 10; i++) {
        auto begin = clock();
        double l = 0.0;
        for (double n = 1; n < limit; n += 4)
        {
            l += (1.0 / n) - (1.0 / (n + 2));
        }
        printf("%1.16f", l * 4);
        printf(" %f sec.\n", (double)(clock() - begin) / CLOCKS_PER_SEC);
        limit *= 10;
    }
    printf("end\n");
    return 0;
}
```
### 実行
```
> gcc -O3 CppProj.cpp
> CppProj
```
### 実行結果
![c++.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/8f653328-adfb-1edc-82c3-fbe41e1c9f50.png)
## C＃

``` cs
using System;

namespace CsProj
{
    class Program
    {
        public static void Main()
        {
            System.Console.WriteLine("start");
            double limit = 10;

            for (int i = 0; i < 10; i++) {
                System.DateTime begin = System.DateTime.Now;
                double l = 0.0;

                for (double n = 1.0; n < limit; n += 4)
                {
                    l += (1.0 / n) - (1.0 / (n + 2));
                }

                System.Console.WriteLine("{0} {1}sec", l * 4,  System.DateTime.Now.Subtract(begin).TotalMilliseconds / 1000);
                limit *= 10;
            }
            System.Console.WriteLine("end");
        }
    }
}
```
### 実行結果
![c#.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/9b58bebe-d67b-68c4-9a8f-63ed049145bd.png)
## Javascript
``` js
console.log( 'start' )

let limit = 10
for (let i = 0; i < 10; i++) {
　　const begin = performance.now()

    let l = 0.0

    for (let n=1; n < limit; n += 4){

        l += (1.0 / n) - (1.0 / (n + 2))

    }
    console.log( l * 4 , `${ ( performance.now() - begin ) / 1000 } sec.` )
    limit *= 10
}
console.log("end")
```
### 実行
```
> node JsProj.js
```
### 実行結果
![js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/6b2e3a0d-168f-67b0-5dde-ec50c1095817.png)
## python
``` py
import time

print( "start" )

limit = 10
for m in range(0, 11):
    begin = time.time()
    n = 1
    l = 0.0
    while n < limit:
        l += (1.0 / n) - (1.0 / (n + 2))
        n += 4
        
    print( l * 4, time.time() - begin, " sec." ) 
    limit *= 10
print( "end" )
```
### 実行
```
> python PyProj.py
``` 
### 実行結果
![py.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/6f1b24ea-c333-9730-40dc-6c6fb4915820.png)
Pythonを使用して1e10桁の計算は時間がかかるため結果が出ませんでした。
# 計測結果
計測結果から、Javascriptが一番早く計算が終わり、次にC++,C#の順に計算が終わり、最長がPythonでした。
Pythonはインタプリタ言語なので、コンパイラ言語のC++とC#、JITコンパイラのJavascriptに比べて非常に計算が遅いです。

# Pythonについて追加検証
Pythonの実行結果が他の言語と比べて実行速度がとびぬけて遅い為、PyPyを使用して改善を試みました。
PyPyはPythonのコードをJITコンパイラで実行するため、実行速度を改善出来る見込みがあります。

コードはPythonの物と同じものを使用して実行しました。
- PyPy 7.3.7 with MSC v.1929 64 bit

## PyPy
``` py
import time

print( "start" )

limit = 10
for i in range(0, 11):
    begin = time.time()
    n = 1
    l = 0.0
    while n < limit:
        l += (1.0 / n) - (1.0 / (n + 2))
        n += 4
        
    print( l * 4, time.time() - begin, " sec." ) 
    limit *= 10
print( "end" )
```
### 実行
```
> pypypre PyProj.py
```
### 実行結果
 ![pypy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/8244429f-1aa6-c003-63be-880aac6fcd42.png)

Pythonと比べて、数十倍の速度を改善しました。しかしJavascriptやC#,C++と比べると遅いです。
原因はPythonのFor文にあるのではないかと思いました。Pythonの計算ではライブラリのNumPyを使用してベクトル化することが多いため、NumPyで計算することでさらに改善できるのではないかと思います
今回は比較対象にC#やC++などがあり、比較が正しくできないと判断したため今回は検証しませんでした。

# まとめ
![Leibniz-result2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/5cb222dc-d800-7b8d-17d3-c79b7671ab4f.png)
![Leibniz-result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359141/644a1b87-f334-79b6-573a-8b8723917ac8.png)


結果から見てJITコンパイラのJavascriptがC++やC#よりも計算が早く出来たことが新たな発見でした。
Pythonはインタプリタ言語なので計算速度は遅いのですが、NumPyやPyPyなどコードの書き方や実行環境を整えれば実行速度の改善は出来そうです。