for loop in python is 10x slower than matlab

前端 未结 4 1530
庸人自扰
庸人自扰 2020-12-11 06:37

I run python 2.7 and matlab R2010a on the same machine, doing nothing, and it gives me 10x different in speed

I looked online, and heard it should be the same order

相关标签:
4条回答
  • 2020-12-11 06:47

    The basic Python implementation, CPython, is not meant to be super-speedy. If you need efficient matlab-style numerical manipulation, use the numpy package or an implementation of Python that is designed for fast work, such as PyPy or even Cython. (Writing a Python extension in C, which will of course be pretty fast, is also a possible solution, but in that case you may as well just use numpy and save yourself the effort.)

    0 讨论(0)
  • 2020-12-11 06:56

    The reason this is happening is related to the JIT compiler, which is optimizing the MATLAB for loop. You can disable/enable the JIT accelerator using feature accel off and feature accel on. When you disable the accelerator, the times change dramatically.

    MATLAB with accel on: Elapsed time is 0.009407 seconds.

    MATLAB with accel off: Elapsed time is 0.287955 seconds.

    python: time cost = 0.0511920452118

    Thus the JIT accelerator is directly causing the speedup that you are noticing. There is another thing that you should consider, which is related to the way that you defined the iteration indices. In both cases, MATLAB and python, you used Iterators to define your loops. In MATLAB you create the actual values by adding the square brackets ([]), and in python you use range instead of xrange. When you make these changes

    % MATLAB
    for i = [1:1000]
        for j = [1:1000]
    
    # python
    for r in range(1000):
      for c in range(1000):
    

    The times become

    MATLAB with accel on: Elapsed time is 0.338701 seconds.

    MATLAB with accel off: Elapsed time is 0.289220 seconds.

    python: time cost = 0.0606048107147

    One final consideration is if you were to add a quick computation to the loop. ie t=t+1. Then the times become

    MATLAB with accel on: Elapsed time is 1.340830 seconds.

    MATLAB with accel off: Elapsed time is 0.905956 seconds. (Yes off was faster)

    python: time cost = 0.147221088409

    I think that the moral here is that the computation speeds of for loops, out-of-the box, are comparable for extremely simple loops, depending on the situation. However, there are other, numerical tools in python which can speed things up significantly, numpy and PyPy have been brought up so far.

    0 讨论(0)
  • 2020-12-11 07:01

    If Python execution performance is really crucial for you, you might take a look at PyPy

    I did your test:

    import time
    for a in range(10):
        start_time = time.time()
        for r in xrange(1000):
            for c in xrange(1000):
                continue
    
        elapsed_time = time.time()-start_time
        print elapsed_time
    

    with standard Python 2.7.3, I get:

    0.0311839580536
    0.0310959815979
    0.0309510231018
    0.0306520462036
    0.0302460193634
    0.0324130058289
    0.0308878421783
    0.0307397842407
    0.0304911136627
    0.0307500362396
    

    whereas, using PyPy 1.9.0 (which corresponds to Python 2.7.2), I get:

    0.00921821594238
    0.0115230083466
    0.00851202011108
    0.00808095932007
    0.00496387481689
    0.00499391555786
    0.00508499145508
    0.00618195533752
    0.005126953125
    0.00482988357544
    

    The acceleration of PyPy is really stunning and really becomes visible when its JIT compiler optimizations outweigh their cost. That's also why I introduced the extra for loop. For this example, absolutely no modification of the code was needed.

    0 讨论(0)
  • 2020-12-11 07:04

    This is just my opinion, but I think the process is a bit more complex. Basically Matlab is an optimized layer of C, so with the appropriate initialization of matrices and minimization of function calls (avoid "." objects-like operators in Matlab) you obtain extremely different results. Consider the simple following example of wave generator with cosine function. Matlab time = 0.15 secs in practical debug session, Python time = 25 secs in practical debug session (Spyder), thus Python becomes 166x slower. Run directly by Python 3.7.4. machine the time is = 5 secs aprox, so still be a non negligible 33x.

    MATLAB:

    AW(1,:) = [800 , 0    ]; % [amp frec]
    AW(2,:) = [300 , 4E-07]; 
    AW(3,:) = [200 , 1E-06];
    AW(4,:) = [ 50 , 4E-06];
    AW(5,:) = [ 30 , 9E-06];
    AW(6,:) = [ 20 , 3E-05];
    AW(7,:) = [ 10 , 4E-05];
    AW(8,:) = [  9 , 5E-04];
    AW(9,:) = [  7 , 7E-04];
    AW(10,:)= [  5 , 8E-03];
    
    phas    = 0
    
    tini    = -2*365 *86400; % 2 years backwards in seconds
    dt      = 200;        % step, 200 seconds
    tfin    = 0;          % present
    vec_t   = ( tini: dt: tfin)'; % vector_time
    
    nt      = length(vec_t);
    vec_t   = vec_t - phas;
    wave    = zeros(nt,1);
    
    for it = 1:nt
        suma = 0;
        t    = vec_t(it,1);
        for iW = 1:size(AW,1)
            suma = suma + AW(iW,1)*cos(AW(iW,2)*t);
        end
        wave(it,1) = suma;
    end
    

    PYTHON:

    import numpy as np
    
    AW      = np.zeros((10,2))
    AW[0,:] = [800 , 0.0]
    AW[1,:] = [300 , 4E-07]; # [amp frec]
    AW[2,:] = [200 , 1E-06];
    AW[3,:] = [ 50 , 4E-06];
    AW[4,:] = [ 30 , 9E-06];
    AW[5,:] = [ 20 , 3E-05];
    AW[6,:] = [ 10 , 4E-05];
    AW[7,:] = [  9 , 5E-04];
    AW[8,:] = [  7 , 7E-04];
    AW[9,:] = [  5 , 8E-03];
    
    phas    = 0
    
    tini    = -2*365 *86400 # 2 years backwards
    dt      = 200
    tfin    = 0           # present
    nt      = round((tfin-tini)/dt) + 1 
    vec_t   = np.linspace(tini,tfin1,nt) - phas
    
    wave    = np.zeros((nt))
    
    for it in range(nt):
        suma   = 0
        t      = vec_t[fil]
        for iW in range(np.size(AW,0)):
            suma = suma + AW[iW,0]*np.cos(AW[iW,1]*t)
        #endfor iW
        wave[it] = suma
    #endfor it
    

    To deal such aspects in Python I would suggest to compile into executable directly to binary the numerical parts that may compromise the project (or for example C or Fortran into executable and be called by Python afterwards). Of course, other suggestions are appreciated.

    0 讨论(0)
提交回复
热议问题