Python数组和MATLAB

时间:2014-04-04 13:29:08

标签: python arrays multithreading matlab numpy

我慢慢切换到Python,我想做一个简单的测试来比较简单数组求和的性能。我生成一个随机的1000x1000数组,并为此数组中的每个值添加一个。

这是我在Python中的脚本:

import time

import numpy
from numpy.random import random

def testAddOne(data):
    """
    Test addOne
    """
    return data + 1

i = 1000
data = random((i,i))
start = time.clock()
for x in xrange(1000): 
    testAddOne(data)

stop = time.clock()
print stop - start

我在MATLAB中的功能:

function test
%parameter declaration
c=rand(1000);

tic
for t = 1:1000
    testAddOne(c);
end
fprintf('Structure: \n')
toc
end

function testAddOne(c)
c = c + 1;
end

Python需要2.77 - 2.79秒,与MATLAB函数相同(我实际上对Numpy印象非常深刻!)。我需要更改为Python脚本才能使用多线程?我不能在MATLAB中工作,因为我没有工具箱。

1 个答案:

答案 0 :(得分:2)

Python中的线程仅适用于线程被阻塞的情况,例如:在获取输入时,这不是这种情况(有关详细信息,请参阅this question的答案)。但是,在Python中很容易实现多处理。一般而言,多处理涵盖here

对您的示例采用类似方法的程序位于

之下
import time
import numpy
from numpy.random import random
from multiprocessing import Process

def testAddOne(data):
    return data + 1

def testAddN(data,N):
    # print "testAddN", N
    for x in xrange(N): 
        testAddOne(data)

if __name__ == '__main__':
    matrix_size = 1000
    num_adds = 10000
    num_processes = 4

    data = random((matrix_size,matrix_size))

    start = time.clock()
    if num_processes > 1:
        processes = [Process(target=testAddN, args=(data,num_adds/num_processes))
                     for i in range(num_processes)]
        for p in processes:
            p.start()
        for p in processes:
            p.join()
    else:
        testAddN(data,num_adds)

    stop = time.clock()
    print "Elapsed", stop - start

使用pool of worker processes连续向不同矩阵添加1的更有用示例如下。

import time
import numpy
from numpy.random import random
from multiprocessing import Pool

def testAddOne(data):
    return data + 1

def testAddN(dataN):
    data,N=dataN
    for x in xrange(N): 
        data = testAddOne(data)
    return data

if __name__ == '__main__':
    num_matrices = 4
    matrix_size = 1000
    num_adds_per_matrix = 2500

    num_processes = 4

    inputs = [(random((matrix_size,matrix_size)), num_adds_per_matrix)
              for i in range(num_matrices)]
    #print inputs # test using, e.g., matrix_size = 2

    start = time.clock()

    if num_processes > 1:
        proc_pool = Pool(processes=num_processes)
        outputs = proc_pool.map(testAddN, inputs)    
    else:
        outputs = map(testAddN, inputs)

    stop = time.clock()
    #print outputs # test using, e.g., matrix_size = 2
    print "Elapsed", stop - start

在这种情况下,testAddN中的代码实际上会调用testAddOne的结果。您可以取消注释打印语句,以检查是否正在完成一些有用的工作。

在这两种情况下,我都将添加总数改为10000;添加量越少,启动流程的成本就越高(但您可以尝试参数)。您也可以尝试使用num_processes。在我的机器上,我发现与使用num_processes=1在同一进程中运行相比,我只有不到2倍的速度,产生了num_processes=4的四个进程。