from random import randint
def random_letter():
return chr(ord(‘a’) + randint(0, 25))
def random_letters(n):
return “”.join([random_letter() for _ in range(n)])
strings = [random_letters(randint(1, 10)) for _ in range(10000)]
2.1 最常规的写法
while循环遍历列表,对字符串进行拼接。平均运行时间1.86毫秒。
def concat_strings_0(strings):
res = “”
n = len(strings)
i = 0
while i < n:
res += strings[i][:3]
i += 1
return res
%timeit concat_strings_0(strings)
1.86 ms ± 74.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.2 for range
代替while循环
避免i += 1
的变量类型检查带来的额外开销。平均运行时间1.55毫秒。
def concat_strings_1(strings):
res = “”
for i in range(len(strings)):
res += strings[i][:3]
return res
%timeit concat_strings_1(strings)
1.55 ms ± 32.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.3 for x in strings
代替for range
避免strings[i]的变量类型检查带来的额外开销。平均运行时间1.32毫秒。
def concat_strings_2(strings):
res = “”
for x in strings:
res += x[:3]
return res
%timeit concat_strings_2(strings)
1.32 ms ± 19.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.4 .join
方法套用生成器表达式
平均运行时间1.06毫秒。
def concat_strings_3(strings):
return “”.join(x[:3] for x in strings)
%timeit concat_strings_3(strings)
1.06 ms ± 15.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.5 .join
方法套用列表解析式
平均运行时间0.85毫秒。
def concat_strings_4(strings):
return “”.join([x[:3] for x in strings])
%timeit concat_strings_4(strings)
858 µs ± 14.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3. 筛选奇数
输入一个列表,要求筛选出该列表中的所有奇数。最终性能提升了3.6倍。
首先创建一个长度为10000的列表。
arr = list(range(10000))
3.1 最常规的写法
创建一个空列表res,while循环遍历列表,将奇数append到res中。平均运行时间1.03毫秒。
def filter_odd_0(arr):
res = []
i = 0
n = len(arr)
while i < n:
if arr[i] % 2:
res.append(arr[i])
i += 1
return res
%timeit filter_odd_0(arr)
1.03 ms ± 34.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.2 for range
代替while循环
避免i += 1
的变量类型检查带来的额外开销。平均运行时间0.965毫秒。
def filter_odd_1(arr):
res = []
for i in range(len(arr)):
if arr[i] % 2:
res.append(arr[i])
i += 1
return res
%timeit filter_odd_1(arr)
965 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.3 for x in arr
代替for range
避免arr[i]
的变量类型检查带来的额外开销。平均运行时间0.430毫秒。
def filter_odd_2(arr):
res = []
for x in arr:
if x % 2:
res.append(x)
return res
%timeit filter_odd_2(arr)
430 µs ± 9.25 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.4 list套用filter函数
平均运行时间0.763毫秒。注意filter函数很慢,在Python 3.6里非常鸡肋。
def filter_odd_3(arr):
return list(filter(lambda x: x % 2, arr))
%timeit filter_odd_3(arr)
763 µs ± 15.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.5 list套用生成器表达式
平均运行时间0.398毫秒。
def filter_odd_4(arr):
return list((x for x in arr if x % 2))
%timeit filter_odd_4(arr)
398 µs ± 16.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.6 带条件的列表推导式
平均运行时间0.290毫秒。
def filter_odd_5(arr):
return [x for x in arr if x % 2]
%timeit filter_odd_5(arr)
290 µs ± 5.54 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
4. 两个数组相加
输入两个长度相同的列表,要求计算出两个列表对应位置的数字之和,返回一个与输入长度相同的列表。最终性能提升了2.7倍。
首先生成两个长度为10000的列表。
arr1 = list(range(10000))
arr2 = list(range(10000))
4.1 最常规的写法
创建一个空列表res,while循环遍历列表,将两个列表对应的元素之和append到res中。平均运行时间1.23毫秒。
def arr_sum_0(arr1, arr2):
i = 0
n = len(arr1)
res = []
while i < n:
res.append(arr1[i] + arr2[i])
i += 1
return res
%timeit arr_sum_0(arr1, arr2)
1.23 ms ± 3.77 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
4.2 for range
代替while循环
避免i += 1
的变量类型检查带来的额外开销。平均运行时间0.997毫秒。
def arr_sum_1(arr1, arr2):
res = []
for i in range(len(arr1)):
res.append(arr1[i] + arr2[i])
return res
%timeit arr_sum_1(arr1, arr2)
997 µs ± 7.42 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
4.3 for i, x in enumerate
代替for range
部分避免arr[i]
的变量类型检查带来的额外开销。平均运行时间0.799毫秒。
def arr_sum_2(arr1, arr2):
res = arr1.copy()
for i, x in enumerate(arr2):
res[i] += x
return res
%timeit arr_sum_2(arr1, arr2)
799 µs ± 16.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
4.4 for x, y in zip
代替for range
避免arr[i]
的变量类型检查带来的额外开销。平均运行时间0.769毫秒。
def arr_sum_3(arr1, arr2):
res = []
for x, y in zip(arr1, arr2):
res.append(x + y)
return res
%timeit arr_sum_3(arr1, arr2)
769 µs ± 12.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)