Pythonのmultiprocessingおよびpipe実行時間

Pythonのmultiprocessingおよびpipeの実行時間計測。

multiprocessing

code

#!/usr/bin/env python
#
# see also : http://docs.python.jp/2.7/library/multiprocessing.html

from sys import stdout
from time import time
from multiprocessing import Process, Pipe

NUMBER = 1000

def measurement(f):
    time_start = time()
    for n in range(NUMBER):
        f()
    time_end = time()
    return time_end - time_start

def dummy():
    pass

def create_process():
    Process()

def start_process():
    Process().start()

def create_pipe():
    Pipe()

def join_process():
    process = Process()
    process.start()
    process.join()

def null_process(pipe1, number):
    for n in range(number):
        pipe1.recv()

def measurement_simplex_pipe():
    time_start = time()
    pipe0, pipe1 = Pipe()
    process = Process(target=null_process, args=(pipe1, NUMBER))
    process.start()
    for n in range(NUMBER):
        pipe0.send(n)
    process.join()
    time_end = time()
    return time_end - time_start

def echo_process(pipe1, number):
    for n in range(number):
        pipe1.send(pipe1.recv())

def measurement_duplex_pipe():
    time_start = time()
    pipe0, pipe1 = Pipe()
    process = Process(target=echo_process, args=(pipe1, NUMBER))
    process.start()
    for n in range(NUMBER):
        pipe0.send(n)
        pipe0.recv()
    process.join()
    time_end = time()
    return time_end - time_start

stdout.write("pass, %f\n" % measurement(dummy))
stdout.write("create process, %f\n" % measurement(create_process))
stdout.write("start process, %f\n" % measurement(start_process))
stdout.write("join process, %f\n" % measurement(join_process))
stdout.write("create pipe, %f\n" % measurement(create_pipe))
stdout.write("simplex pipe, %f\n" % measurement_simplex_pipe())
stdout.write("duplex pipe, %f\n" % measurement_duplex_pipe())

Python 2.7

処理 実行時間 (ms)
pass 0.000079
create process 0.003357
start process 0.245117
join process 0.976598
create pipe 0.011329
simplex pipe 0.003099
duplex pipe 0.011246

Python 3.5

処理 実行時間 (ms)
pass 0.000067
create process 0.003868
start process 0.415079
join process 1.492507
create pipe 0.035219
simplex pipe 0.007089
duplex pipe 0.047015

pipe

code

#!/usr/bin/env python
#
# see also : http://docs.python.jp/2.7/library/multiprocessing.html
#            http://docs.chainer.org/en/stable/tutorial/basic.html

from sys import stdout
from time import time
from multiprocessing import Process, Pipe
from chainer import Chain, ChainList
from chainer.links import Linear

NUMBER = 1000

def measurement(f):
    time_start = time()
    for n in range(NUMBER):
        f()
    time_end = time()
    return time_end - time_start

def null_process(pipe1, number):
    for n in range(number):
        pipe1.recv()

def measurement_simplex_pipe(klass):
    time_start = time()
    pipe0, pipe1 = Pipe()
    process = Process(target=null_process, args=(pipe1, NUMBER))
    process.start()
    for n in range(NUMBER):
        pipe0.send(klass)
    process.join()
    time_end = time()
    return time_end - time_start

def echo_process(pipe1, number):
    for n in range(number):
        pipe1.send(pipe1.recv())

def measurement_duplex_pipe(klass):
    time_start = time()
    pipe0, pipe1 = Pipe()
    process = Process(target=echo_process, args=(pipe1, NUMBER))
    process.start()
    for n in range(NUMBER):
        pipe0.send(klass)
        pipe0.recv()
    process.join()
    time_end = time()
    return time_end - time_start

class MyChain(Chain):
    def __init__(self):
        super(MyChain, self).__init__(
            l1=Linear(784, 100),
            l2=Linear(100, 100),
            l3=Linear(100, 10)
        )

    def __call__(self, x):
        h1 = relu(self.l1(x))
        h2 = relu(self.l2(h1))
        return self.l3(h2)

class MyChainList(ChainList):
    def __init__(self):
        super(MyChainList, self).__init__(
            Linear(784, 100),
            Linear(100, 100),
            Linear(100, 10)
        )

    def __call__(self, x):
        h1 = relu(self[0](x))
        h2 = relu(self[1](h1))
        return self.l3(h2)

classies = [Chain, ChainList, MyChain, MyChainList]

for k in classies:
    stdout.write("create instance %s, %f\n" % (k, measurement(lambda: k())))

for k in classies:
    stdout.write("simplex pipe %s, %f\n" % (k, measurement_simplex_pipe(k)))

for k in classies:
    stdout.write("duplex pipe %s, %f\n" % (k, measurement_duplex_pipe(k)))

Python 2.7

処理 実行時間 (ms)
create instance Chain 0.003006
create instance ChainList 0.001593
create instance MyChain 3.788916
create instance MyChainList 3.780761
simplex pipe Chain 0.005608
simplex pipe ChainList 0.005627
simplex pipe MyChain 0.006494
simplex pipe MyChainList 0.006871
duplex pipe Chain 0.029776
duplex pipe ChainList 0.034982
duplex pipe MyChain 0.033020
duplex pipe MyChainList 0.035376

Python 3.5

処理 実行時間 (ms)
create instance Chain 0.002134
create instance ChainList 0.001779
create instance MyChain 4.150180
create instance MyChainList 4.152344
simplex pipe Chain 0.013076
simplex pipe ChainList 0.013038
simplex pipe MyChain 0.013047
simplex pipe MyChainList 0.010454
duplex pipe Chain 0.065646
duplex pipe ChainList 0.070427
duplex pipe MyChain 0.076342
duplex pipe MyChainList 0.079283