Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB比Python快吗(简单的小实验)_Python_Matlab_Performance Testing - Fatal编程技术网

MATLAB比Python快吗(简单的小实验)

MATLAB比Python快吗(简单的小实验),python,matlab,performance-testing,Python,Matlab,Performance Testing,我读过这个()我发现它有很多假设 我在一台仍然运行Windows XP的旧电脑上做了这个小实验 在MATLAB R2010b中,我在命令窗口中复制并粘贴了以下代码: tic x = 0.23; for i = 1:100000000 x = 4 * x * (1 - x); end toc x 结果是: Elapsed time is 0.603583 seconds. x = 0.947347510922557 然后,我用以下脚本保存了一个py文件: import time

我读过这个()我发现它有很多假设

我在一台仍然运行Windows XP的旧电脑上做了这个小实验

在MATLAB R2010b中,我在命令窗口中复制并粘贴了以下代码:

tic
x = 0.23;
for i = 1:100000000
  x = 4 * x * (1 - x);
end
toc
x
结果是:

Elapsed time is 0.603583 seconds.

x =

    0.947347510922557
然后,我用以下脚本保存了一个
py
文件:

import time
t = time.time()
x = 0.23
for i in range(100000000): x = 4 * x * (1 - x)
elapsed = time.time() - t
print(elapsed)
print(x)
我按了F5,结果是

49.78125
0.9473475109225565
在MATLAB中,它花费了0.60秒;在Python中,它花费了49.78秒(永恒!!)

所以问题是:有没有一种简单的方法让Python和MATLAB一样快

特别是:如何更改我的
py
脚本,使其运行速度与MATLAB一样快


更新

我在PyPy中尝试了相同的实验(复制和粘贴相同的代码,如上所述):它与以前一样在同一台机器上用1.0470001697540283秒完成

我用1e9循环重复了这些实验

MATLAB结果:

Elapsed time is 5.599789 seconds.
1.643573442831396e-004
PyPy
结果:

8.609999895095825
0.00016435734428313955
我还尝试了正常的
while
循环,得到了类似的结果:

t = time.time()
x = 0.23
i = 0
while (i < 1000000000):
    x = 4 * x * (1 - x)
    i += 1

elapsed = time.time() - t
elapsed
x
过一会儿,我将尝试
NumPy

一个(受过一定教育的)猜测是python不会在您的代码上执行。这意味着MATLAB代码正在执行一个大型计算,而不是许多(!)较小的计算。这是使用PyPy而不是作为PyPy的CPython的主要原因


如果您使用的是Python2.X,那么您应该用
range
代替
xrange
,因为
range
(在Python2.X中)创建了一个要迭代的列表。

首先,使用
time
不是这样测试代码的好方法。但是让我们忽略这一点


当您的代码执行大量循环并在每次循环中重复非常类似的工作时,JIT将做得非常好。当代码每次都做完全相同的事情时,对于可以从循环中提取的常量值,它会做得更好。另一方面,CPython必须为每个循环迭代执行多个字节码,因此速度会很慢。从我的机器上的快速测试来看,CPython 3.4.1需要24.2秒,而PyPy 2.4.0/3.2.5需要0.0059秒

IronPython和Jython也是JIT编译的(尽管使用的是更通用的JVM和.NET JIT),因此对于这类工作,它们往往也比CPython更快


通过使用数组和向量操作而不是Python列表和循环,通常也可以在CPython本身中加速这样的工作。例如,以下代码需要0.011秒:

i = np.arange(10000000)
i[:] = 4 * x * (1-x)
当然,在这种情况下,我们显式地只计算一次值并复制10000000次。但我们可以强迫它一次又一次地进行实际计算,仍然只需要0.12秒:

i = np.zeros((10000000,))
i = 4 * (x+i) * (1-(x+i))

其他选项包括在中编写部分代码(编译为Python的C扩展)和使用,JIT在CPython中编译代码。对于这样的玩具程序,如果您只想优化一次24秒的过程,那么自动生成和编译C代码所花费的时间可能会超过运行C代码而不是Python代码所节省的时间。但在现实生活中的数值编程中,两者都非常有用。(两人都能很好地与NumPy合作。)

而且总是会有新的项目出现。

Q:我如何更改我的
py
脚本,使其运行速度与MATLAB一样快? 由于已经为您提供了许多知识丰富的指导,让我添加我的两分钱(以及一些定量结果)

(同样地,我希望您能原谅跳过
:假设一个更复杂的计算任务)

  • 检查代码是否有任何可能的算法改进、值重用和寄存器/缓存友好安排(
    numpy.asfortranarray()
    等)

  • 尽可能在numpy中使用矢量化代码执行/循环展开

  • 对于代码的稳定部分,同样使用LLVM编译器
    numba

  • 仅在代码的最终级别上使用其他(JIT)编译器技巧(nogil=True,nopython=True),以避免常见的过早优化错误

可能的成就确实是巨大的:

初始代码样本取自FX arena(毫秒、微秒和(浪费的)纳秒确实很重要-检查50%的市场事件,您有远少于900毫秒的时间(端到端双向交易),而不是HFT…)来处理
EMA(200,关闭)
-过去200 Gbps USD烛光/棒的非平凡指数移动平均数,约5200多行:

import numba
#@jit                                               # 2015-06 @autojit deprecated
@numba.jit('f8[:](i8,f8[:])')
def numba_EMA_fromPrice( N_period, aPriceVECTOR ):
    EMA = aPriceVECTOR.copy()
    alf = 2. / ( N_period + 1 )
    for aPTR in range( 1, EMA.shape[0] ):
        EMA[aPTR] = EMA[aPTR-1] + alf * ( aPriceVECTOR[aPTR] - EMA[aPTR-1] )
    return EMA
对于这个“经典”代码,仅仅是
numba
编译步骤就比普通的python/numpy代码执行有了改进

21x下降到大约半毫秒

#   541L
# ___________vvvvv__________# !!!     !!! 
#@numba.jit( nogil = True ) # JIT w/o GIL-lock w/ multi-CORE ** WARNING: ThreadSafe / DataCoherency measures **
#   aClk.start();numba_EMA_fromPrice_EFF_ALGO( 200, price_H4_CLOSE );aClk.stop()
#   Out[126]: 149929L                               # JIT-compile-pass
#   Out[127]:    284L                               # re-use 0.3 [ms] v/s 11.5 [ms] CPython
#   Out[128]:    256L
从大约11499[美国](是的,从大约11500微秒到只有541[美国])

但是,如果您对算法更加谨慎,并重新设计它,以便更智能、更高效地使用资源,那么结果将更加丰硕

@numba.jit
def numba_EMA_fromPrice_EFF_ALGO( N_period, aPriceVECTOR ):
    alfa    = 2. / ( N_period + 1 )
    coef    = ( 1 - alfa )
    EMA     = aPriceVECTOR * alfa
    EMA[1:]+= EMA[0:-1]    * coef
    return EMA

#   aClk.start();numba_EMA_fromPrice_EFF_ALGO( 200, price_H4_CLOSE );aClk.stop()
#   Out[112]: 160814L                               # JIT-compile-pass
#   Out[113]:    331L                               # re-use 0.3 [ms] v/s 11.5 [ms] CPython
#   Out[114]:    311L
#   Out[115]:    324L
以及多CPU核心处理的最终抛光触摸


46x加速到大约四分之一毫秒

#   541L
# ___________vvvvv__________# !!!     !!! 
#@numba.jit( nogil = True ) # JIT w/o GIL-lock w/ multi-CORE ** WARNING: ThreadSafe / DataCoherency measures **
#   aClk.start();numba_EMA_fromPrice_EFF_ALGO( 200, price_H4_CLOSE );aClk.stop()
#   Out[126]: 149929L                               # JIT-compile-pass
#   Out[127]:    284L                               # re-use 0.3 [ms] v/s 11.5 [ms] CPython
#   Out[128]:    256L

作为最后的奖金。更快有时并不等于更好。 惊讶?

不,这没什么奇怪的。尝试让MATLAB计算SQRT(2),精度为小数点后约500.000.000位。就这样

纳秒确实很重要。这里的数字越大,精度就是目标。


这不值得花时间和精力吗?当然,是的