【发布时间】:2021-12-25 05:17:39
【问题描述】:
在下面的代码中,我创建了两个具有相同值的列表:一个未排序 (s_not) 的列表,另一个已排序 (s_yes)。这些值由 randint() 创建。我为每个列表运行一些循环并计时。
import random
import time
for x in range(1,9):
r = 10**x # do different val for the bound in randint()
m = int(r/2)
print("For rand", r)
# s_not is non sorted list
s_not = [random.randint(1,r) for i in range(10**7)]
# s_yes is sorted
s_yes = sorted(s_not)
# do some loop over the sorted list
start = time.time()
for i in s_yes:
if i > m:
_ = 1
else:
_ = 1
end = time.time()
print("yes", end-start)
# do the same to the unsorted list
start = time.time()
for i in s_not:
if i > m:
_ = 1
else:
_ = 1
end = time.time()
print("not", end-start)
print()
有输出:
For rand 10
yes 1.0437555313110352
not 1.1074268817901611
For rand 100
yes 1.0802974700927734
not 1.1524150371551514
For rand 1000
yes 2.5082249641418457
not 1.129960298538208
For rand 10000
yes 3.145440101623535
not 1.1366300582885742
For rand 100000
yes 3.313387393951416
not 1.1393756866455078
For rand 1000000
yes 3.3180911540985107
not 1.1336982250213623
For rand 10000000
yes 3.3231537342071533
not 1.13503098487854
For rand 100000000
yes 3.311596393585205
not 1.1345293521881104
因此,当增加 randint() 中的界限时,排序列表上的循环会变慢。为什么?
【问题讨论】:
-
n=10^7 可能是矫枉过正。低至 n=10^5 给了我可比较的结果,并且只需要大约 2 秒即可运行。
-
对于那些归因于缓存未命中的人:所有
r的列表大小相同,但在数字超过 10**100 之前,运行时没有差异 -
与this Java question基本相同的问题。
-
@Davislor:那没什么区别; Python 的
list已经是连续的了,排序是通过交换数据来完成的。sorted没有就地执行(有点;它创建了一个新的list,然后对 that 进行了就地排序),但这在很大程度上是无关紧要的;list存储指向其中各种对象的指针,而不是原始数据,因此两个lists 都在为相同的对象设置别名。 -
@nocomment:我们都是对的,我们只是使用不同的上下文。是的,在内部,CPython 使用的是 TimSort(修改后的合并排序),它不会就地排序,也不会随其进行交换。我说的是 Python 层的可观察行为(无论如何,对于
list.sort,你不能告诉sorted的任何这些,因为它在内部生成了新的list,你不能检查它),其中原始的list被就地修改,并且其中包含相同的对象(没有重新创建东西)。如果 Davislor 说的是真正的数组(array模块或numpy),那我就离题了。