パラレルベンチマーク [C++/D/C#/VB/JS/HSP/Python/Ruby]

重い処理はマルチスレッドとかマルチプロセスでPrallel処理を行う物とは良く聞く話。
じゃあ、どこまで速度が改善されるの?ということで、実測してみる。
(ついでに言語ごとの速度テストも)
Parallel処理は勿論のこと、それ以外のマルチスレッド処理が使えるものはそちらでもテスト。
HSP以外は標準ライブラリのみを使用する。

# 実行条件
OS:Windows7 32bit
コア数:4

C++:Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24215.1
D:DMD32 D Compiler v2.066.1
C#:Microsoft (R) Visual C# Compiler バージョン 1.3.1.60616
VB:Microsoft (R) Visual Basic Compiler バージョン 1.3.1.60616
Node.js:node v7.3.0
HSP:HSP 3.4
Python:Python 3.6.0
Ruby:Ruby 2.3.1

## 処理方法一覧
* C++
	+ for(シングルスレッド)
	+ future(マルチスレッド)
	+ parallel for(OpenMP)(マルチスレッド)
* D
	+ for(シングルスレッド)
	+ Thread(マルチスレッド)
	+ parallel foreach(マルチスレッド)
* C<sapn>#</span>
	+ for(シングルスレッド)
	+ Task(マルチスレッド)
	+ Parallel.For(マルチスレッド)
* VisualBasic
	+ For(シングルスレッド)
	+ Task(マルチスレッド)
	+ Parallel.For(マルチスレッド)
* Node.js(JavaScript)
	+ for(シングルスレッド)
	+ Promise(シングルスレッド)
	+ cluster(マルチプロセス)
* HSP
	+ repeat(シングルスレッド)
	+ for(シングルスレッド)
	+ mstThread(mistプラグイン)(マルチスレッド)
* Python
	+ for(シングルスレッド)
	+ future Thread(マルチスレッド)
	+ future Process(マルチプロセス)
* Ruby
	+ for(シングルスレッド)
	+ Thread(マルチスレッド)

## テスト内容
2000000000回及び5000000000回のインクリメント処理を4つに分けて行う。
言語ごとの実装は後述する。

#実行結果

| 計算回数[回]        | 2,000,000,000 | 5,000,000,000 |
|:--------------------|--------------:|--------------:|
| **Language/Process** | **Time[ms]**  | **Time[ms]**  |
| **C++**             |               |               |
| for                 |             0 |          4593 |
| future              |             0 |          2319 |
| parallel for        |             0 |          2358 |
| **D**               |               |               |
| for                 |           646 |          4673 |
| Thread              |           342 |          2351 |
| parallel foreach    |           312 |          2345 |
| **C<sapn>#</span>** |               |               |
| for                 |           642 |          4577 |
| Task                |           332 |          2539 |
| Parallel.For        |           316 |          2465 |
| **VisualBasic**     |               |               |
| For                 |          1827 |          4716 |
| Task                |           940 |          2506 |
| Parallel.For        |           942 |          2414 |
| **Node.js**         |               |               |
| for                 |          2461 |          9485 |
| Promise             |          2443 |          9499 |
| cluster             |          1555 |          5517 |
| **HSP**             |               |               |
| repeat              |        106000 |        282400 |
| for                 |        326000 |        951600 |
| mstThread           |         59300 |        215300 |
| **Python**          |               |               |
| for                 |        197500 |        499000 |
| future Thread       |        205800 |        498500 |
| future Process      |        134400 |        272600 |
| **Ruby**            |               |               |
| for                 |        160900 |        485100 |
| Thread              |        158800 |        468100 |

※HSP、Python、Rubyは処理時間がかかるため、処理量を100分の1(100ずつ加算)にし、その代わり計測時間を100倍としている。

# あとがき
## 結果について
基本的にマルチスレッドやマルチプロセスは有効で、4倍までとは言わないものの大よそ2倍程度までは速度を引き上げられることを確認。
Threadを使ってもPrallelを使っても効力としては同程度。
必要ならどちらを使っても良いのかな。
ただし、PythonとRubyのマルチスレッドに関してはシングルスレッドとあまり変わる結果とはならなかった。Rubyは同時に一つまでしかスレッドを動かせないとか聞いたけれど、Pythonもそういうことなのかな。
ちなみにJavaScriptのPromiseについてはシングルスレッドなのでそのまんまという所。

## 言語ごとの計算速度について
今回色々試していて、単純なループやインクリメントの速度も見てみた。
静的型付け言語については型の重要さが見て取れた。
データは録っていないが、インクリメントする場合は一般的に整数型の方が浮遊小数点型に比べ、早くなる傾向があるみたいだ。
また、同じ整数型でもlongよりもintの方が速くなる様子。
特にC++の速度の低下っぷりは著しい。
それでも、D、C#、VBと並んでいる位なので、遅くはないけど。

あとは、D言語とC#の差異にはあれっ?と言う感じ。
C++とD言語はネイティブコンパイルなので、中間言語型の.NET言語に対しては明確な差が出ると思っていた。

それと、C#とほぼ同じコードを書いているはずなのにVBが遅かったことにビックリというか残念だった。
生成されるアセンブリとか解読すれば原因はわかるのだろうか。

* 追記:CILに変換してアセンブリを覗いてみた。  
  正直、よくわからないけど、大まかの流れは似ている。  
  しかし、見ていくとC#ではaddとなっているところがVBではadd.ovfとなっていた。  
  これは、オーバーフローの検査をするものらしく、それがVBではオーバーヘッドとなっていたのかなぁと想像する。

次にNode.js。
静的言語勢に何だかんだ大差付けられていないあたり流石JITコンパイルといったところ。
なお、ビット論理和演算子("|")と0で小細工して内部的に整数型に固定させると僅かに速度が上がるみたい。
(asm.jsの型指定で使われているものらしい)
結果は載せてないけど、2000000000回の計算時点で100～200msの差が出ている。
しかし、計算回数が5000000000回の時では返って2倍くらい遅くなったのでそちらでは普通のインクリメントとした。
あとは、整数維持し続けると普通にオーバーフローする。

HSP。
聞いていた話だけど、forマクロは非常に遅い。
コンパイルとは言っても結局はインタプリタ言語なため、速度はお察し。
intを使い続けるとオーバーフローするけど、doubleを使っても速度的に目立った大差はないみたいだ。

Ruby、Python。
パフォーマンス的には似たり寄ったりなインタプリタ言語二つ。
Rubyの方が微妙に早いように見える。

# 実装
## 2,000,000,000回版
### C++
```cpp:
#include<iostream>
#include<vector>
#include<thread>
#include<future>
#include<omp.h>
using namespace std;
using namespace std::chrono;

const int cores=4;
int maxsum=2000000000;

int main(){
	maxsum/=cores;
	int sum=0;

	cout<<"for"<<endl;
	auto sw0=system_clock::now();
	for(int n=0;n<cores;n++){
		int esum=0;
		for(int i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	auto sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;

	cout<<"for future"<<endl;
	sw0=system_clock::now();
	sum=0;
	vector<future<void>> futures;
	for(int n=0;n<cores;n++){
		futures.push_back(async(launch::async,[&]{
			int esum=0;
			for(int i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}));
	}
	for(auto &t:futures){
		t.wait();
	}
	sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;

	cout<<"OpenMP parallel for"<<endl;
	sw0=system_clock::now();
	sum=0;
	#pragma omp parallel for reduction(+:sum)
	for(int n=0;n<cores;n++){
		int esum=0;
		for(int i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;
}
```

### D
```d:
import std.stdio;
import std.datetime;
import core.thread;
import std.parallelism;
import std.range;
import std.array;

StopWatch sw;
immutable int cores=4;
int maxsum=2000000000;

void main(){
	maxsum/=cores;
	int maxsum=maxsum;

	writeln("for");
	sw.start();
	int sum=0;
	for(int n=0;n<cores;n++){
		int esum=0;
		for(int i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);

	sw.reset();

	writeln("for Thread");
	sw.start();
	sum=0;
	auto tg=new ThreadGroup();

	for(int n;n<cores;n++){
		auto t=new Thread(delegate(){
			int esum=0;
			for(int i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		});
		tg.add(t);
		t.start();
	}
	tg.joinAll();
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);

	sw.reset();
	writeln("foreach parallel");
	sw.start();
	sum=0;
	foreach(n;parallel(cores.iota.array)){
		int esum=0;
		for(int i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);
}
```

### C<span>#</span>
```csharp:
using System;
using System.Diagnostics;
using System.Threading.Tasks;

static class Program{
	static Stopwatch sw=new Stopwatch();
	const int cores=4;
	static int maxsum=2000000000;

	static void Main(){
		maxsum/=cores;

		Console.WriteLine("for");
		sw.Start();
		int sum=0;
		for(int n=0;n<cores;n++){
			int esum=0;
			for(int i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);

		sw.Reset();

		Console.WriteLine("ConvertAll Task");
		sw.Start();
		sum=0;
		var Taskss=Array.ConvertAll(new object[cores],n=>Task.Run(()=>{
			int esum=0;
			for(int i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}));
		Task.WaitAll(Taskss);
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);

		sw.Reset();

		Console.WriteLine("Parallel.For");
		sw.Start();
		sum=0;
		Parallel.For(0,cores,(n)=>{
			int esum=0;
			for(int i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		});
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);
	}
}
```

### VisualBasic.NET
```vbnet:
Option Strict On
Imports System.Console
Imports System.Diagnostics
Imports System.Threading.Tasks

Module Program
	Dim sw As New StopWatch
	Const cores As Integer=4
	Dim maxsum As Integer=2000000000

	Sub Main
		maxsum\=cores

		WriteLine("For")
		sw.Start()
		Dim sum As Integer=0
		For n As Integer=0 To cores-1
			Dim esum As Integer=0
			For i As Integer=0 To maxsum-1
				esum+=1
			Next
			sum+=esum
		Next
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)

		sw.Reset()

		WriteLine("CovertAll Task")
		sw.Start()
		sum=0
		Dim Taskes=Array.ConvertAll(New Object(cores-1){},Function(n)Task.Run(Sub()
			Dim esum As Integer=0
			For i As Integer=0 To maxsum-1
				esum+=1
			Next
			sum+=esum
		End Sub))
		Task.WaitAll(Taskes)
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)

		sw.Reset()

		WriteLine("Parallel.For")
		sw.Start()
		sum=0
		Parallel.For(0,cores,Sub(n)
			Dim esum As Integer=0
			For i As Integer=0 To maxsum-1
				esum+=1
			Next
			sum+=esum
		End Sub)
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)
	End Sub
End Module
```

### Node.js(JavaScript)
```js:
"use strict";
var cluster=require("cluster");

const cores=4;
var maxsum=2000000000;

function main(){
	maxsum/=cores;

	console.log("for");
	console.time("time");
	var sum=0
	for(var n=0;n<cores;n=0|n+1){
		var esum=0;
		for(var i=0;i<maxsum;i=0|i+1){
			esum=0|esum+1;
		}
		sum=0|sum+esum;
	}
	console.timeEnd("time");
	console.log("%d",sum);

	console.log("map Promise");
	console.time("time");
	sum=0;
	var Promises=new Array(cores).fill().map(n=>new Promise(resolve=>{
		var esum=0
		for(var i=0;i<maxsum;i=0|i+1){
			esum=0|esum+1;
		}
		sum=0|sum+esum;
		resolve();
	}));
	Promise.all(Promises).then(()=>{
		console.timeEnd("time");
		console.log("%d",sum);

		console.log("map cluster");
		console.time("time");
		sum=0;
		var clusters=Array(cores).fill().map(n=>new Promise(resolve=>{
			cluster.setupMaster({args:[maxsum]});
			cluster.fork().once("message",esum=>{
				sum=0|sum+esum;
				resolve();
			});
		}));
		Promise.all(clusters).then(()=>{
			console.timeEnd("time");
			console.log("%d",sum);
		});
	});
}

if(cluster.isWorker){
	maxsum=parseInt(process.argv[2]);
	var esum=0;
	for(var i=0;i<maxsum;i=0|i+1){
		esum=0|esum+1;
	}
	process.send(esum);
	cluster.worker.kill();
	process.exit();
}

main();
```

### HSP
```objc++:
#packopt name "timeHsp"
#runtime "hsp3cl"
#uselib "Kernel32"
#cfunc global GetTickCount "GetTickCount"
#include "mist.hsp"

#const global cores 4
maxsum=2000000000

#module Program
	#deffunc main
		maxsum@/=100
		maxsum@/=cores

		mes "repeat"
		sw=GetTickCount()
		sum=0
		repeat cores
			esum=0
			repeat maxsum@
				esum+=100
			loop
			sum+=esum
		loop
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes sum

		mes "repert for"
		sw=GetTickCount()
		sum=0
		repeat cores
			esum=0
			for i,0,maxsum@
				esum+=100
			next
			sum+=esum
		loop
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes sum

		mes "repert mstThread"
		sw=GetTickCount()
		mstOpenHspLib
		sum=0
		mstBind "sum",sum
		mstCompile {"
			#deffunc worker int maxsum,local esum
				esum=0
				repeat maxsum
					esum+=100
				loop
				sum+=esum
			return
		"}
		mstSetWorkerNum cores
		repeat cores
			mstThreadCall "worker",maxsum@
		loop
		mstThreadJoin
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes sum
	return
#global

main
```

### Python
```py3:
import time
import functools
import concurrent.futures
futures=concurrent.futures

cores=4
maxsum=2000000000

def main():
	global maxsum
	maxsum/=100
	maxsum=int(maxsum/cores)

	print("for")
	sw=time.time()
	sum=0
	for n in range(0,cores):
		esum=0
		for i in range(0,maxsum):
			esum+=100
		sum+=esum
	print("time: {0:.2f}ms".format((time.time()-sw)*1000))
	print("sum: {0}".format(sum))

	print("map future Thread")
	with futures.ThreadPoolExecutor() as TP:
		sw=time.time()
		sum=0
		workers=list(map(lambda n:TP.submit(worker,maxsum),range(0,cores)))
		for esum in futures.wait(workers)[0]:
			sum+=esum.result()
		print("time: {0:.2f}ms".format((time.time()-sw)*1000))
		print("sum: {0}".format(sum))

	print("map future Process")
	with futures.ProcessPoolExecutor() as TP:
		sw=time.time()
		sum=0
		workers=list(map(lambda n:TP.submit(worker,maxsum),range(0,cores)))
		for esum in futures.wait(workers)[0]:
			sum+=esum.result()
		print("time: {0:.2f}ms".format((time.time()-sw)*1000))
		print("sum: {0}".format(sum))

def worker(maxsum):
	esum=0
	for i in range(0,maxsum):
		esum+=100
	return esum

if __name__=="__main__":
	main()
```

### Ruby
```ruby:
require "thwait"
require "benchmark"

@cores=4
@maxsum=2000000000

def main()
	puts "for"
	@maxsum/=100
	@maxsum/=@cores

	sw=Benchmark.realtime do
		@sum=0
		for n in 0..@cores-1
			esum=0
			for i in 0..@maxsum-1
				esum+=100
			end
			@sum+=esum
		end
	end
	puts "time: #{(sw*1000).round(2)}ms"
	puts @sum

	puts "for Thread"
	sw2=Benchmark.realtime do
		@sum=0
		@threads=[]
		for n in 0..@cores-1
			@threads.push(Thread.new do
				esum=0
				for i in 0..@maxsum-1
					esum+=100
				end
				@sum+=esum
			end)
		end
		ThreadsWait.all_waits(*@threads)
	end
	puts "time: #{(sw2*1000).round(2)}ms"
	puts @sum
end

main()
```



## 5,000,000,000回版
### C++
```cpp:
#include<iostream>
#include<vector>
#include<thread>
#include<future>
#include<omp.h>
using namespace std;
using namespace std::chrono;

const int cores=4;
long long maxsum=5000000000;

int main(){
	maxsum/=cores;
	long long sum=0;

	cout<<"for"<<endl;
	auto sw0=system_clock::now();
	for(int n=0;n<cores;n++){
		unsigned esum=0;
		for(unsigned i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	auto sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;

	cout<<"for future"<<endl;
	sw0=system_clock::now();
	sum=0;
	vector<future<void>> futures;
	for(int n=0;n<cores;n++){
		futures.push_back(async(launch::async,[&]{
			unsigned esum=0;
			for(unsigned i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}));
	}
	for(auto &t:futures){
		t.wait();
	}
	sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;

	cout<<"OpenMP parallel for"<<endl;
	sw0=system_clock::now();
	sum=0;
	#pragma omp parallel for reduction(+:sum)
	for(int n=0;n<cores;n++){
		unsigned esum=0;
		for(unsigned i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw=duration_cast<milliseconds>(system_clock::now()-sw0).count();
	cout<<"time: "<<sw<<"ms"<<endl;
	cout<<sum<<endl;
}
```

### D
```d:
import std.stdio;
import std.datetime;
import core.thread;
import std.parallelism;
import std.range;
import std.array;

StopWatch sw;
immutable int cores=4;
long maxsum=5000000000;

void main(){
	maxsum/=cores;
	long maxsum=maxsum;

	writeln("for");
	sw.start();
	long sum=0;
	for(int n=0;n<cores;n++){
		uint esum=0;
		for(uint i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);

	sw.reset();

	writeln("for Thread");
	sw.start();
	sum=0;
	auto tg=new ThreadGroup();

	for(int n;n<cores;n++){
		auto t=new Thread(delegate(){
			uint esum=0;
			for(uint i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		});
		tg.add(t);
		t.start();
	}
	tg.joinAll();
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);

	sw.reset();
	writeln("foreach parallel");
	sw.start();
	sum=0;
	foreach(n;parallel(cores.iota.array)){
		uint esum=0;
		for(uint i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	sw.stop();
	writeln("time: ",sw.peek().to!("msecs",real)(),"ms");
	writefln("%d",sum);
}
```

### C<span>#</span>
```csharp:
using System;
using System.Diagnostics;
using System.Threading.Tasks;

static class Program{
	static Stopwatch sw=new Stopwatch();
	const int cores=4;
	static long maxsum=5000000000;

	static void Main(){
		maxsum/=cores;

		Console.WriteLine("for");
		sw.Start();
		long sum=0;
		for(int n=0;n<cores;n++){
			uint esum=0;
			for(uint i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);

		sw.Reset();

		Console.WriteLine("ConvertAll Task");
		sw.Start();
		sum=0;
		var Taskss=Array.ConvertAll(new object[cores],n=>Task.Run(()=>{
			uint esum=0;
			for(uint i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		}));
		Task.WaitAll(Taskss);
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);

		sw.Reset();

		Console.WriteLine("Parallel.For");
		sw.Start();
		sum=0;
		Parallel.For(0,cores,(n)=>{
			uint esum=0;
			for(uint i=0;i<maxsum;i++){
				esum++;
			}
			sum+=esum;
		});
		sw.Stop();
		Console.WriteLine($"time: {sw.ElapsedMilliseconds}ms");
		Console.WriteLine("{0}",sum);
	}
}
```

### VisualBasic.NET
```vbnet:
Option Strict On
Imports System.Console
Imports System.Diagnostics
Imports System.Threading.Tasks

Module Program
	Dim sw As New StopWatch
	Const cores As Integer=4
	Dim maxsum As Long=5000000000

	Sub Main
		maxsum\=cores

		WriteLine("For")
		sw.Start()
		Dim sum As Long=0
		For n As Integer=0 To cores-1
			Dim esum As UInteger=0
			For i As UInteger=0 To CUInt(maxsum-1)
				esum+=CUInt(1)
			Next
			sum+=esum
		Next
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)

		sw.Reset()

		WriteLine("CovertAll Task")
		sw.Start()
		sum=0
		Dim Taskes=Array.ConvertAll(New Object(cores-1){},Function(n)Task.Run(Sub()
			Dim esum As UInteger=0
			For i As UInteger=0 To CUInt(maxsum-1)
				esum+=CUInt(1)
			Next
			sum+=esum
		End Sub))
		Task.WaitAll(Taskes)
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)

		sw.Reset()

		WriteLine("Parallel.For")
		sw.Start()
		sum=0
		Parallel.For(0,cores,Sub(n)
			Dim esum As UInteger=0
			For i As UInteger=0 To CUInt(maxsum-1)
				esum+=CUInt(1)
			Next
			sum+=esum
		End Sub)
		sw.Stop()
		WriteLine($"time: {sw.ElapsedMilliseconds}ms")
		WriteLine("{0}",sum)
	End Sub
End Module
```

### Node.js(JavaScript)
```js:
"use strict";
var cluster=require("cluster");

const cores=4;
var maxsum=5000000000;

function main(){
	maxsum/=cores;

	console.log("for");
	console.time("time");
	var sum=0
	for(var n=0;n<cores;n++){
		var esum=0;
		for(var i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
	}
	console.timeEnd("time");
	console.log("%d",sum);

	console.log("map Promise");
	console.time("time");
	sum=0;
	var Promises=new Array(cores).fill().map(n=>new Promise(resolve=>{
		var esum=0
		for(var i=0;i<maxsum;i++){
			esum++;
		}
		sum+=esum;
		resolve();
	}));
	Promise.all(Promises).then(()=>{
		console.timeEnd("time");
		console.log("%d",sum);

		console.log("map cluster");
		console.time("time");
		sum=0;
		var clusters=Array(cores).fill().map(n=>new Promise(resolve=>{
			cluster.setupMaster({args:[maxsum]});
			cluster.fork().once("message",esum=>{
				sum+=esum;
				resolve();
			});
		}));
		Promise.all(clusters).then(()=>{
			console.timeEnd("time");
			console.log("%d",sum);
		});
	});
}

if(cluster.isWorker){
	maxsum=parseInt(process.argv[2]);
	var esum=0
	for(var i=0;i<maxsum;i++){
		esum++;
	}
	process.send(esum);
	cluster.worker.kill();
	process.exit();
}

main();
```

### HSP
```objc++:
#packopt name "timeHsp"
#runtime "hsp3cl"
#uselib "Kernel32"
#cfunc global GetTickCount "GetTickCount"
#include "mist.hsp"

#const global cores 4
maxsum=5000000000.0

#module Program
	#deffunc main
		maxsum@/=100
		maxsum@/=cores

		mes "repeat"
		sw=GetTickCount()
		sum=0.0
		repeat cores
			esum=0.0
			repeat maxsum@
				esum+=100
			loop
			sum+=esum
		loop
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes strf("%.0f",sum)

		mes "repert for"
		sw=GetTickCount()
		sum=0.0
		repeat cores
			esum=0.0
			for i,0,maxsum@
				esum+=100
			next
			sum+=esum
		loop
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes strf("%.0f",sum)

		mes "repert mstThread"
		sw=GetTickCount()
		mstOpenHspLib
		sum=0.0
		mstBind "sum",sum
		mstCompile {"
			#deffunc worker int maxsum,local esum
				esum=0.0
				repeat maxsum
					esum+=100
				loop
				sum+=esum
			return
		"}
		mstSetWorkerNum cores
		repeat cores
			mstThreadCall "worker",maxsum@
		loop
		mstThreadJoin
		mes "time: "+(GetTickCount()-sw)+"ms"
		mes strf("%.0f",sum)
	return
#global

main
```

### Python
```py3:
import time
import functools
import concurrent.futures
futures=concurrent.futures

cores=4
maxsum=5000000000

def main():
	global maxsum
	maxsum/=100
	maxsum=int(maxsum/cores)

	print("for")
	sw=time.time()
	sum=0
	for n in range(0,cores):
		esum=0
		for i in range(0,maxsum):
			esum+=100
		sum+=esum
	print("time: {0:.2f}ms".format((time.time()-sw)*1000))
	print("sum: {0}".format(sum))

	print("map future Thread")
	with futures.ThreadPoolExecutor() as TP:
		sw=time.time()
		sum=0
		workers=list(map(lambda n:TP.submit(worker,maxsum),range(0,cores)))
		for esum in futures.wait(workers)[0]:
			sum+=esum.result()
		print("time: {0:.2f}ms".format((time.time()-sw)*1000))
		print("sum: {0}".format(sum))

	print("map future Process")
	with futures.ProcessPoolExecutor() as TP:
		sw=time.time()
		sum=0
		workers=list(map(lambda n:TP.submit(worker,maxsum),range(0,cores)))
		for esum in futures.wait(workers)[0]:
			sum+=esum.result()
		print("time: {0:.2f}ms".format((time.time()-sw)*1000))
		print("sum: {0}".format(sum))

def worker(maxsum):
	esum=0
	for i in range(0,maxsum):
		esum+=100
	return esum

if __name__=="__main__":
	main()
```

### Ruby
```ruby:
require "thwait"
require "benchmark"

@cores=4
@maxsum=5000000000

def main()
	puts "for"
	@maxsum/=100
	@maxsum/=@cores

	sw=Benchmark.realtime do
		@sum=0
		for n in 0..@cores-1
			esum=0
			for i in 0..@maxsum-1
				esum+=100
			end
			@sum+=esum
		end
	end
	puts "time: #{(sw*1000).round(2)}ms"
	puts @sum

	puts "for Thread"
	sw2=Benchmark.realtime do
		@sum=0
		@threads=[]
		for n in 0..@cores-1
			@threads.push(Thread.new do
				esum=0
				for i in 0..@maxsum-1
					esum+=100
				end
				@sum+=esum
			end)
		end
		ThreadsWait.all_waits(*@threads)
	end
	puts "time: #{(sw2*1000).round(2)}ms"
	puts @sum
end

main()
```