python numpy numba 计算速度对比

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 17:59
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit

def python_list(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c

@jit
def python_list_with_numba(n):
#   a = range(n)
#   b = range(n)
#   c = []
#   for i in range(len(a)):
#       a[i] = i ** 2
#       b[i] = i ** 3
#       c.append(a[i] + b[i])
#   return c
    return python_list(n)

def numpy_vector(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@jit
def numpy_vector_with_numba(n):
#   x = np.arange(n)
#   y = np.arange(n)
#   z = x**2 + y**3
#   return z
    return numpy_vector(n)


if __name__ == '__main__':
    t1 = Timer('python_list(1000000)','from __main__ import python_list')
    t2 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t3 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t4 = Timer('numpy_vector(1000000)','from __main__ import numpy_vector')
    t5 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')
    t6 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')

    take_time1 = t1.timeit(50)
    take_time2 = t2.timeit(50)
    take_time3 = t3.timeit(50)
    take_time4 = t4.timeit(50)
    take_time5 = t5.timeit(50)
    take_time6 = t6.timeit(50)

    print("python list:%s" % take_time1)
    print("python list with numba comp:%s" % take_time2)
    print("python list with numba after comp:%s" % take_time3)
    print("numpy vector:%s" % take_time4)
    print("numpy vector with numba comp:%s" % take_time5)
    print("numpy vector with numba after comp:%s" % take_time6)

output

python list:8.37137699127
python list with numba comp:8.26541399956
python list with numba after comp:8.33281493187
numpy vector:0.529839992523
numpy vector with numba comp:0.539204835892
numpy vector with numba after comp:0.524770021439

好像调用函数对与 numba来说是有有影响的.调用函数的话numba 就起不到加速的效果了.下面去掉函数调用

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 18:05
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit

def python_list(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c

@jit
def python_list_with_numba(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c

def numpy_vector(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@jit
def numpy_vector_with_numba(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z


if __name__ == '__main__':
    t1 = Timer('python_list(1000000)','from __main__ import python_list')
    t2 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t3 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t4 = Timer('numpy_vector(1000000)','from __main__ import numpy_vector')
    t5 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')
    t6 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')

    take_time1 = t1.timeit(50)
    take_time2 = t2.timeit(50)
    take_time3 = t3.timeit(50)
    take_time4 = t4.timeit(50)
    take_time5 = t5.timeit(50)
    take_time6 = t6.timeit(50)

    print("python list:%s" % take_time1)
    print("python list with numba comp:%s" % take_time2)
    print("python list with numba after comp:%s" % take_time3)
    print("numpy vector:%s" % take_time4)
    print("numpy vector with numba comp:%s" % take_time5)
    print("numpy vector with numba after comp:%s" % take_time6)

output

python list:8.16710710526
python list with numba comp:9.53106093407
python list with numba after comp:9.40612602234
numpy vector:0.188210964203
numpy vector with numba comp:0.314162015915
numpy vector with numba after comp:0.0830471515656

numpy在计算上比python 要快.加上numba后numpy似乎可以提高1倍的速度.
numba编译的那次速度是比较慢的.

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 21:27
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit
from numba import njit

def python_list(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c

@jit
def python_list_with_numba(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c

def numpy_vector(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@jit
def numpy_vector_with_numba(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@njit(fastmath=True)
def numpy_vector_with_numba_fast(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@njit(parallel=True)
def numpy_vector_with_numba_parallel(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z

@njit(fastmath=True, parallel=True)
def numpy_vector_with_numba_fast_parallel(n):
    x = np.arange(n)
    y = np.arange(n)
    z = x**2 + y**3
    return z


if __name__ == '__main__':
    t1 = Timer('python_list(1000000)','from __main__ import python_list')
    t2 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t3 = Timer('python_list_with_numba(1000000)','from __main__ import python_list_with_numba')
    t4 = Timer('numpy_vector(1000000)','from __main__ import numpy_vector')
    t5 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')
    t6 = Timer('numpy_vector_with_numba(1000000)','from __main__ import numpy_vector_with_numba')
    t7 = Timer('numpy_vector_with_numba_fast(1000000)','from __main__ import numpy_vector_with_numba_fast')
    t8 = Timer('numpy_vector_with_numba_fast(1000000)','from __main__ import numpy_vector_with_numba_fast')

    t9 = Timer('numpy_vector_with_numba_parallel(1000000)','from __main__ import numpy_vector_with_numba_parallel')
    t10 = Timer('numpy_vector_with_numba_parallel(1000000)','from __main__ import numpy_vector_with_numba_parallel')

    t11 = Timer('numpy_vector_with_numba_fast_parallel(1000000)','from __main__ import numpy_vector_with_numba_fast_parallel')
    t12 = Timer('numpy_vector_with_numba_fast_parallel(1000000)','from __main__ import numpy_vector_with_numba_fast_parallel')

    take_time1 = t1.timeit(50)
    take_time2 = t2.timeit(50)
    take_time3 = t3.timeit(50)
    take_time4 = t4.timeit(50)
    take_time5 = t5.timeit(50)
    take_time6 = t6.timeit(50)
    take_time7 = t7.timeit(50)
    take_time8 = t8.timeit(50)
    take_time9 = t9.timeit(50)
    take_time10 = t10.timeit(50)
    take_time11 = t11.timeit(50)
    take_time12 = t12.timeit(50)

    print("python_list:%s" % take_time1)
    print("python_list_with_numba compile:%s" % take_time2)
    print("python_list_with_numba after compile:%s" % take_time3)
    print("numpy_vector:%s" % take_time4)
    print("numpy_vector_with_numba compile:%s" % take_time5)
    print("numpy_vector_with_numba after compile:%s" % take_time6)
    print("numpy_vector_with_numba_fast compile:%s" % take_time7)
    print("numpy_vector_with_numba_fast after compile:%s" % take_time8)
    print("numpy_vector_with_numba_parallel compile:%s" % take_time9)
    print("numpy_vector_with_numba_parallel after compile:%s" % take_time10)
    print("numpy_vector_with_numba_fast_parallel compile:%s" % take_time11)
    print("numpy_vector_with_numba_fast_parallel after compile:%s" % take_time12)

output

python_list:8.22160506248
python_list_with_numba compile:9.52428817749
python_list_with_numba after compile:9.4302740097
numpy_vector:0.18684220314
numpy_vector_with_numba compile:0.313122034073
numpy_vector_with_numba after compile:0.0834867954254
numpy_vector_with_numba_fast compile:0.166754961014
numpy_vector_with_numba_fast after compile:0.0827031135559
numpy_vector_with_numba_parallel compile:0.353137016296
numpy_vector_with_numba_parallel after compile:0.0367288589478
numpy_vector_with_numba_fast_parallel compile:0.359938144684
numpy_vector_with_numba_fast_parallel after compile:0.0356090068817

加上parallel 能够提速6倍.看起来确实加速了.

下面测试下矩阵相乘 是否能被加速

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 22:22
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit
from numba import njit

def dot(x,y):
    z = np.dot(x,y)
    return z

@jit
def dot_numba(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True)
def dot_numba_fast(x,y):
    z = np.dot(x,y)
    return z

@njit(parallel=True)
def dot_numba_parallel(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True, parallel=True)
def dot_numba_fast_parallel(x,y):
    z = np.dot(x,y)
    return z

if __name__ == '__main__':

    x = np.random.randn(100,100)
    y = np.random.randn(100,100)

    t1 = Timer('dot(x,y)','from __main__ import dot,x,y')
    t2 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t3 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t4 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')
    t5 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')

    t6 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')
    t7 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')

    t8 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')
    t9 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')

    take_time1 = t1.timeit(90)
    take_time2 = t2.timeit(90)
    take_time3 = t3.timeit(90)
    take_time4 = t4.timeit(90)
    take_time5 = t5.timeit(90)
    take_time6 = t6.timeit(90)
    take_time7 = t7.timeit(90)
    take_time8 = t8.timeit(90)
    take_time9 = t9.timeit(90)

    print("dot:%s" % take_time1)
    print("dot_numba compilation:%s" % take_time2)
    print("dot_numba after compilation:%s" % take_time3)
    print("dot_numba_fast compilation:%s" % take_time4)
    print("dot_numba_fast after compilation:%s" % take_time5)
    print("dot_numba_parallel compilation:%s" % take_time6)
    print("dot_numba_parallel after compilation:%s" % take_time7)
    print("dot_numba_fast_parallel compilation:%s" % take_time8)
    print("dot_numba_fast_parallel after compilation:%s" % take_time9)

output

dot:0.0045690536499
dot_numba compilation:0.161776065826
dot_numba after compilation:0.00354194641113
dot_numba_fast compilation:0.0609059333801
dot_numba_fast after compilation:0.00446605682373
dot_numba_parallel compilation:0.0760118961334
dot_numba_parallel after compilation:0.00450396537781
dot_numba_fast_parallel compilation:0.0754170417786
dot_numba_fast_parallel after compilation:0.00403594970703

能够看到编译的时候会更慢,编译后的numba也不比numpy快.
下面把矩阵变大看下效果

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 22:26
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit
from numba import njit

def dot(x,y):
    z = np.dot(x,y)
    return z

@jit
def dot_numba(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True)
def dot_numba_fast(x,y):
    z = np.dot(x,y)
    return z

@njit(parallel=True)
def dot_numba_parallel(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True, parallel=True)
def dot_numba_fast_parallel(x,y):
    z = np.dot(x,y)
    return z

if __name__ == '__main__':

    x = np.random.randn(1000,1000)
    y = np.random.randn(1000,1000)

    t1 = Timer('dot(x,y)','from __main__ import dot,x,y')
    t2 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t3 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t4 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')
    t5 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')

    t6 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')
    t7 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')

    t8 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')
    t9 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')

    take_time1 = t1.timeit(90)
    take_time2 = t2.timeit(90)
    take_time3 = t3.timeit(90)
    take_time4 = t4.timeit(90)
    take_time5 = t5.timeit(90)
    take_time6 = t6.timeit(90)
    take_time7 = t7.timeit(90)
    take_time8 = t8.timeit(90)
    take_time9 = t9.timeit(90)

    print("dot:%s" % take_time1)
    print("dot_numba compilation:%s" % take_time2)
    print("dot_numba after compilation:%s" % take_time3)
    print("dot_numba_fast compilation:%s" % take_time4)
    print("dot_numba_fast after compilation:%s" % take_time5)
    print("dot_numba_parallel compilation:%s" % take_time6)
    print("dot_numba_parallel after compilation:%s" % take_time7)
    print("dot_numba_fast_parallel compilation:%s" % take_time8)
    print("dot_numba_fast_parallel after compilation:%s" % take_time9)

output

dot:1.29017019272
dot_numba compilation:1.43309783936
dot_numba after compilation:1.20246815681
dot_numba_fast compilation:1.28146505356
dot_numba_fast after compilation:1.18621397018
dot_numba_parallel compilation:1.3401529789
dot_numba_parallel after compilation:1.44713497162
dot_numba_fast_parallel compilation:1.34533500671
dot_numba_fast_parallel after compilation:1.19588494301

依然没有看到加速的迹象.

#!/usr/bin/python
# -*- coding: utf-8 -*-
#####################################
# File name : test.py
# Create date : 2019-01-05 17:11
# Modified date : 2019-01-05 22:39
# Author : DARREN
# Describe : not set
# Email : [email protected]
#####################################
from __future__ import division
from __future__ import print_function

import numpy as np
from timeit import Timer
from numba import jit
from numba import njit

def dot(x,y):
    z = np.dot(x,y)
    return z

@jit
def dot_numba(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True)
def dot_numba_fast(x,y):
    z = np.dot(x,y)
    return z

@njit(parallel=True)
def dot_numba_parallel(x,y):
    z = np.dot(x,y)
    return z

@njit(fastmath=True, parallel=True)
def dot_numba_fast_parallel(x,y):
    z = np.dot(x,y)
    return z

if __name__ == '__main__':

    x = np.random.randn(4000,4000)
    y = np.random.randn(4000,4000)

    t1 = Timer('dot(x,y)','from __main__ import dot,x,y')
    t2 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t3 = Timer('dot_numba(x,y)','from __main__ import dot_numba,x,y')
    t4 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')
    t5 = Timer('dot_numba_fast(x,y)','from __main__ import dot_numba_fast,x,y')

    t6 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')
    t7 = Timer('dot_numba_parallel(x,y)','from __main__ import dot_numba_parallel,x,y')

    t8 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')
    t9 = Timer('dot_numba_fast_parallel(x,y)','from __main__ import dot_numba_fast_parallel,x,y')

    take_time1 = t1.timeit(10)
    take_time2 = t2.timeit(10)
    take_time3 = t3.timeit(10)
    take_time4 = t4.timeit(10)
    take_time5 = t5.timeit(10)
    take_time6 = t6.timeit(10)
    take_time7 = t7.timeit(10)
    take_time8 = t8.timeit(10)
    take_time9 = t9.timeit(10)

    print("dot:%s" % take_time1)
    print("dot_numba compilation:%s" % take_time2)
    print("dot_numba after compilation:%s" % take_time3)
    print("dot_numba_fast compilation:%s" % take_time4)
    print("dot_numba_fast after compilation:%s" % take_time5)
    print("dot_numba_parallel compilation:%s" % take_time6)
    print("dot_numba_parallel after compilation:%s" % take_time7)
    print("dot_numba_fast_parallel compilation:%s" % take_time8)
    print("dot_numba_fast_parallel after compilation:%s" % take_time9)

output

dot:7.37525200844
dot_numba compilation:7.05400204659
dot_numba after compilation:7.02080202103
dot_numba_fast compilation:7.13517785072
dot_numba_fast after compilation:6.97198486328
dot_numba_parallel compilation:6.88464617729
dot_numba_parallel after compilation:6.97216892242
dot_numba_fast_parallel compilation:7.04679107666
dot_numba_fast_parallel after compilation:7.12123513222

numba 对于矩阵相乘似乎没有加速效果

你可能感兴趣的:(python,人工智能,numpy)