重い処理はマルチスレッドとかマルチプロセスで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#
- 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# | ||
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++
#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
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#
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
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)
"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
#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
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
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++
#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
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#
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
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)
"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
#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
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
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()