LoginSignup
6
7

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-12-26

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7