В настоящее время я изучаю CS, и меня постоянно поражает, насколько мощным является питон. Недавно я провел небольшой эксперимент, чтобы проверить стоимость формирования списков с пониманием по сравнению с отдельной функцией. Например:
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.
Смотрите графики:
Наложение без увеличения
Я нашел эти результаты интригующими. Хотя оба метода имеют обозначение O (n) с большим О, затраты времени на составление одного и того же списка меньше для понимания.
У меня есть дополнительная информация, в том числе тот же тест, проведенный со списком, составленным сначала с пониманием, а затем с помощью автономной функции.
Мне еще предстоит провести тест без сборки мусора.
person
tgabb
schedule
23.03.2017