Python:形成具有理解功能的列表与独立功能的成本
Python : Cost of forming list with comprehension vs standalone function
在 python 中,使用理解或独立功能制作列表的成本更高?
看来我没能找到以前问同样问题的帖子。虽然其他答案详细介绍了 python 的字节和内部工作原理,这确实很有帮助,但我觉得可视化图表有助于表明存在持续趋势。
我对 python 的底层工作还没有足够的了解,所以这些答案对我来说有点陌生,无法尝试理解。
我目前是 CS 的本科生,我一直对 python 的强大感到惊讶。我最近做了一个小实验来测试通过理解与独立函数形成列表的成本。例如:
def make_list_of_size(n):
retList = []
for i in range(n):
retList.append(0)
return retList
创建一个包含零的大小为 n 的列表。
众所周知,这个函数是O(n)。我想探索以下的成长:
def comprehension(n):
return [0 for i in range(n)]
列表相同。
让我们一起探索吧!
这是我用来计时的代码,请注意函数调用的顺序(我先用哪种方式列出了列表)。我首先使用独立函数制作列表,然后使用理解。我还没有学习如何关闭这个实验的垃圾收集,所以,有一些固有的测量错误,在垃圾收集开始时带来。
'''
file: listComp.py
purpose: to test the cost of making a list with comprehension
versus a standalone function
'''
import time as T
def get_overhead(n):
tic = T.time()
for i in range(n):
pass
toc = T.time()
return toc - tic
def make_list_of_size(n):
aList = [] #<-- O(1)
for i in range(n): #<-- O(n)
aList.append(n) #<-- O(1)
return aList #<-- O(1)
def comprehension(n):
return [n for i in range(n)] #<-- O(?)
def do_test(size_i,size_f,niter,file):
delta = 100
size = size_i
while size <= size_f:
overhead = get_overhead(niter)
reg_tic = T.time()
for i in range(niter):
reg_list = make_list_of_size(size)
reg_toc = T.time()
comp_tic = T.time()
for i in range(niter):
comp_list = comprehension(size)
comp_toc = T.time()
#--------------------
reg_cost_per_iter = (reg_toc - reg_tic - overhead)/niter
comp_cost_pet_iter = (comp_toc - comp_tic - overhead)/niter
file.write(str(size)+","+str(reg_cost_per_iter)+
","+str(comp_cost_pet_iter)+"\n")
print("SIZE: "+str(size)+ " REG_COST = "+str(reg_cost_per_iter)+
" COMP_COST = "+str(comp_cost_pet_iter))
if size == 10*delta:
delta *= 10
size += delta
def main():
fname = input()
file = open(fname,'w')
do_test(100,1000000,2500,file)
file.close()
main()
我做了三个测试。其中两个最大列表大小为 100000,第三个最大为 1*10^6
查看地块:
Overlay with NO ZOOM
我发现这些结果很有趣。尽管这两种方法都有 O(n) 的大 O 表示法,但就时间而言,制作相同列表的理解成本较低。
我有更多信息要分享,包括首先使用理解列表完成的相同测试,然后使用独立函数。
我还没有 运行 没有垃圾收集的测试。
在 python 中,使用理解或独立功能制作列表的成本更高?
看来我没能找到以前问同样问题的帖子。虽然其他答案详细介绍了 python 的字节和内部工作原理,这确实很有帮助,但我觉得可视化图表有助于表明存在持续趋势。
我对 python 的底层工作还没有足够的了解,所以这些答案对我来说有点陌生,无法尝试理解。
我目前是 CS 的本科生,我一直对 python 的强大感到惊讶。我最近做了一个小实验来测试通过理解与独立函数形成列表的成本。例如:
def make_list_of_size(n):
retList = []
for i in range(n):
retList.append(0)
return retList
创建一个包含零的大小为 n 的列表。
众所周知,这个函数是O(n)。我想探索以下的成长:
def comprehension(n):
return [0 for i in range(n)]
列表相同。
让我们一起探索吧!
这是我用来计时的代码,请注意函数调用的顺序(我先用哪种方式列出了列表)。我首先使用独立函数制作列表,然后使用理解。我还没有学习如何关闭这个实验的垃圾收集,所以,有一些固有的测量错误,在垃圾收集开始时带来。
'''
file: listComp.py
purpose: to test the cost of making a list with comprehension
versus a standalone function
'''
import time as T
def get_overhead(n):
tic = T.time()
for i in range(n):
pass
toc = T.time()
return toc - tic
def make_list_of_size(n):
aList = [] #<-- O(1)
for i in range(n): #<-- O(n)
aList.append(n) #<-- O(1)
return aList #<-- O(1)
def comprehension(n):
return [n for i in range(n)] #<-- O(?)
def do_test(size_i,size_f,niter,file):
delta = 100
size = size_i
while size <= size_f:
overhead = get_overhead(niter)
reg_tic = T.time()
for i in range(niter):
reg_list = make_list_of_size(size)
reg_toc = T.time()
comp_tic = T.time()
for i in range(niter):
comp_list = comprehension(size)
comp_toc = T.time()
#--------------------
reg_cost_per_iter = (reg_toc - reg_tic - overhead)/niter
comp_cost_pet_iter = (comp_toc - comp_tic - overhead)/niter
file.write(str(size)+","+str(reg_cost_per_iter)+
","+str(comp_cost_pet_iter)+"\n")
print("SIZE: "+str(size)+ " REG_COST = "+str(reg_cost_per_iter)+
" COMP_COST = "+str(comp_cost_pet_iter))
if size == 10*delta:
delta *= 10
size += delta
def main():
fname = input()
file = open(fname,'w')
do_test(100,1000000,2500,file)
file.close()
main()
我做了三个测试。其中两个最大列表大小为 100000,第三个最大为 1*10^6
查看地块:
Overlay with NO ZOOM
我发现这些结果很有趣。尽管这两种方法都有 O(n) 的大 O 表示法,但就时间而言,制作相同列表的理解成本较低。
我有更多信息要分享,包括首先使用理解列表完成的相同测试,然后使用独立函数。
我还没有 运行 没有垃圾收集的测试。