python matlab性能对比_性能:Matlab与Python

I recently switched from Matlab to Python. While converting one of my lengthy codes, I was surprised to find Python being very slow. I profiled and traced the problem with one function hogging up time. This function is being called from various places in my code (being part of other functions which are recursively called). Profiler suggests that 300 calls are made to this function in both Matlab and Python.

In short, following codes summarizes the issue at hand:

MATLAB

The class containing the function:

classdef ExampleKernel1 < handle

methods (Static)

function [kernel] = kernel_2D(M,x,N,y)

kernel = zeros(M,N);

for i= 1 : M

for j= 1 : N

% Define the custom kernel function here

kernel(i , j) = sqrt((x(i , 1) - y(j , 1)) .^ 2 + ...

(x(i , 2) - y(j , 2)) .^2 );

end

end

end

end

end

and the script to call test.m:

xVec=[

49.7030 78.9590

42.6730 11.1390

23.2790 89.6720

75.6050 25.5890

81.5820 53.2920

44.9680 2.7770

38.7890 78.9050

39.1570 33.6790

33.2640 54.7200

4.8060 44.3660

49.7030 78.9590

42.6730 11.1390

23.2790 89.6720

75.6050 25.5890

81.5820 53.2920

44.9680 2.7770

38.7890 78.9050

39.1570 33.6790

33.2640 54.7200

4.8060 44.3660

];

N=size(xVec,1);

kex1=ExampleKernel1;

tic

for i=1:300

K=kex1.kernel_2D(N,xVec,N,xVec);

end

toc

Gives the output

clear all

>> test

Elapsed time is 0.022426 seconds.

>> test

Elapsed time is 0.009852 seconds.

PYTHON 3.4

Class containing the function CustomKernels.py:

from numpy import zeros

from math import sqrt

class CustomKernels:

"""Class for defining the custom kernel functions"""

@staticmethod

def exampleKernelA(M, x, N, y):

"""Example kernel function A"""

kernel = zeros([M, N])

for i in range(0, M):

for j in range(0, N):

# Define the custom kernel function here

kernel[i, j] = sqrt((x[i, 0] - y[j, 0]) ** 2 + (x[i, 1] - y[j, 1]) ** 2)

return kernel

and the script to call test.py:

import numpy as np

from CustomKernels import CustomKernels

from time import perf_counter

xVec = np.array([

[49.7030, 78.9590],

[42.6730, 11.1390],

[23.2790, 89.6720],

[75.6050, 25.5890],

[81.5820, 53.2920],

[44.9680, 2.7770],

[38.7890, 78.9050],

[39.1570, 33.6790],

[33.2640, 54.7200],

[4.8060 , 44.3660],

[49.7030, 78.9590],

[42.6730, 11.1390],

[23.2790, 89.6720],

[75.6050, 25.5890],

[81.5820, 53.2920],

[44.9680, 2.7770],

[38.7890, 78.9050],

[39.1570, 33.6790],

[33.2640, 54.7200],

[4.8060 , 44.3660]

])

N = xVec.shape[0]

kex1 = CustomKernels.exampleKernelA

start=perf_counter()

for i in range(0,300):

K = kex1(N, xVec, N, xVec)

print(' %f secs' %(perf_counter()-start))

Gives the output

%run test.py

0.940515 secs

%run test.py

0.884418 secs

%run test.py

0.940239 secs

RESULTS

Comparing the results it seems Matlab is about 42 times faster after a "clear all" is called and then 100 times faster if script is run multiple times without calling "clear all". That is at least and order of magnitude if not two orders of magnitudes faster. This is a very surprising result for me. I was expecting the result to be the other way around.

Can someone please shed some light on this?

Can someone suggest a faster way to perform this?

SIDE NOTE

I have also tried to use numpy.sqrt which makes the performance worse, therefore I am using math.sqrt in Python.

EDIT

The for loops for calling the functions are purely fictitious. They are there just to "simulate" 300 calls to the function. As I described earlier, the kernel functions (kernel_2D in Matlab and kex1 in Python) are called from various different places in the program. To make the problem shorter, I "simulate" the 300 calls using the for loop. The for loops inside the kernel functions are essential and unavoidable because of the structure of the kernel matrix.

EDIT 2

解决方案

You want to get rid of those for loops. Try this:

def exampleKernelA(M, x, N, y):

"""Example kernel function A"""

i, j = np.indices((N, M))

# Define the custom kernel function here

kernel[i, j] = np.sqrt((x[i, 0] - y[j, 0]) ** 2 + (x[i, 1] - y[j, 1]) ** 2)

return kernel

You can also do it with broadcasting, which may be even faster, but a little less intuitive coming from MATLAB.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值