为什么处理随机列表比处理有序列表要快得多?

Gab*_*iel 7 python performance

我试图提高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)
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

我需要处理一个有序列表整数(即:a1a3),所以我的问题是:

为什么随机列表的处理速度比没有生成的有序列表快得多numpy

use*_*ica 7

你的b,a2a3列表是NumPy标量的a1列表,而你的列表是普通的Python整数列表.将NumPy标量与普通Python标量进行比较需要进行大量额外的类型检查和强制,因此func(a1, b)需要将NumPy标量与普通Python标量进行比较的测试执行速度最慢.

如果你创建b一个Python内联列表(通过调用tolist方法而不是list函数),时间差是相反的.

您可能需要考虑使用Python set或NumPy的类似集的操作来执行任务.