我试图提高func
函数的性能,我发现生成aX
列表的简单更改可以提高性能:
import timeit
import numpy as np
def func(a, b):
return [_ for _ in a if _ not in b]
Na, Nb = 10000, 5000
b = list(np.random.randint(1000, size=Nb))
# Ordered list of Na integers
a1 = [_ for _ in range(Na)]
# Random list of Na integers
a2 = list(np.random.randint(Na, size=Na))
# Ordered list of Na integers generated with numpy
a3 = list(np.arange(Na))
start_time = timeit.default_timer()
ab1 = func(a1, b)
abt1 = timeit.default_timer() - start_time
print("Time ab1", abt1)
start_time = timeit.default_timer()
ab2 = func(a2, b)
abt2 = timeit.default_timer() - start_time
print("Time ab2", abt2)
start_time = timeit.default_timer()
ab3 = func(a3, b)
abt3 = timeit.default_timer() - start_time
print("Time ab3", abt3)
print("Ratio 1/2:", abt1 / abt2)
print("Ratio 1/3:", abt1 / abt3)
在Python 2.7.13中,结果如下:
('Time ab1', 5.296088933944702)
('Time ab2', 1.5520200729370117)
('Time ab3', 1.5581469535827637)
('Ratio 1/2:', 3.412384302428827)
('Ratio 1/3:', 3.3989662667998095)
在Python 3.5.2中,差异甚至更大:
Time ab1 6.758207322000089
Time ab2 1.5693355060011527
Time ab3 1.5148192759988888
Ratio 1/2: 4.306413317073784
Ratio 1/3: 4.461395117608107
我需要处理有序列表整数(即:a1
或a3
),所以我的问题是:
为什么随机列表的处理速度比使用numpy
生成的有序列表不快得多?
答案 0 :(得分:7)
您的b
,a2
和a3
列表是NumPy标量列表,而您的a1
列表是普通Python整数列表。将NumPy标量与普通Python标量进行比较需要额外类型检查和强制的批次,因此需要将NumPy标量与普通Python标量进行比较的func(a1, b)
测试执行速度最慢。
如果您使b
列出了Python整数(通过调用tolist
method而不是list
函数),则时差会相反。
您可能需要考虑使用Python set
或NumPy set-like operations来执行您的任务。
答案 1 :(得分:1)
正如所讨论的那样here numpy数组比python列表快得多。这就是为什么numpy数组看起来更快,因为当你调用list()
函数时仍然使用numpy数组。
使用numpy .tolist()
函数将NumPy数组一直转换为常规Python对象(如user2357112所指出)并且性能差异消失,请参阅:
import timeit
import numpy as np
def func(a, b):
return [_ for _ in a if _ not in b]
Na, Nb = 10000, 5000
b = list(np.random.randint(Na, size=Nb)) # len: 5000, max: 9999
# Ordered list of Na integers
a1 = [_ for _ in range(Na)] # len: 10000, max: 9999
# Random list of Na integers
a2 = np.random.randint(Na, size=Na).tolist() # len: 10000, max: 9999
# Ordered list of Na integers generated with numpy
a3 = np.arange(Na).tolist()
start_time = timeit.default_timer()
ab1 = func(a1, b)
abt1 = timeit.default_timer() - start_time
print("Time ab1", abt1)
start_time = timeit.default_timer()
ab2 = func(a2, b)
abt2 = timeit.default_timer() - start_time
print("Time ab2", abt2)
start_time = timeit.default_timer()
ab3 = func(a3, b)
abt3 = timeit.default_timer() - start_time
print("Time ab3", abt3)
print("Ratio 1/2:", abt1 / abt2)
print("Ratio 1/3:", abt1 / abt3)
#Time ab1 4.622085004015502
#Time ab2 4.598610720638726
#Time ab3 4.63976530848255
#Ratio 1/2: 1.005104646773301
#Ratio 1/3: 0.9961893968139456
希望这能回答你的第一个问题!