Я прошу об этом в общем, так как я не могу опубликовать фактический код по различным причинам. Делается в IPython NotebookPython: Сроки создания объекта в цикле/понимание/сопоставление против одноразового
Я создал класс структурированную, как это следующим образом (это требует NumPy)
class MyClassName(object):
def __init__(self, filename):
self.filename = filename
self.read_binary_file() # Run these on object creation
self.calculate_parameters()
self.check_for_errors()
...
def read_binary_file(self): # This requires numpy.
# # The file is 250MB binary and
# # ultimately yields a numpy array
# # 32 x 32 x 100000 element
...
def calculate_parameters(self):
...
def check_for_errors(self):
...
def other_function1(self):
...
def other_function2(self):
т.д.
код звук. Я могу сделать следующий
q = MyClassName('testfile.dat') # Instantiate an object
q.other_function1() # Invoke methods
т.д.
%timeit q = MyClassName('testfile.dat')
дает около 0,9 секунд для создания этого
Но, если у меня есть список файлов filenames = ['f1.dat', 'f2.dat', ..., 'f10.dat']
и создать объекты в пределах цикла, понимания или карты
Chomp = map(MyClassName, filenames)
Chomp = [ MyClassName(j) for j in filenames ]
Chomp = []
for j in filenames:
Chomp.append(MyClassName(j))
Для создания каждого объекта требуется более 3,5 секунд. Цикл занимает 3,5 сек/файл х количество файлов для завершения
Что я пробовал: Я посмотрел информацию о создании списка, список добавить тайминги, управление памятью/предположение, отключение/повторное включение сбор мусора после создания каждого объекта и т. д.
Я также импортировал прогон cprofile для создания одного объекта.
Все данные сообщают около 3,5 секунд. cprofile говорит, что числовое двоичное чтение принимало 2,5 секунды 3,5 с для создания одного объекта. Но эта же процедура вызывается, когда я создаю отдельный объект за пределами цикла или cprofile.
Это только создание одного объекта, который идет быстро.
Я бегу на машине под Windows 7 и контролировал диспетчер задач. В какой-то момент это выглядело так, как будто я вытащил из физической памяти и был заменен страницей, поэтому перезагрузился, перезапустил iPython/Notebook, включил только одно ядро и имел мало других программ. Загрузка памяти снизилась, но производительность петли не улучшилась.
Я новичок в OOP в целом, работаю с Python в течение нескольких месяцев и заинтересован в понимании того, что происходит, поэтому я могу кодировать более подходящим образом.
У меня есть шанс, что когда вы приурочили '% timeit q = MyClassName ('testfile.dat')' файл уже был кэширован в памяти, потому что вы к нему обращались раньше? Это может привести к значительно более низкому результату. –
Я попытался создать кучу файлов по одному, и каждый тайм-аут на <1 секунду. Но, поскольку я много экспериментировал, я не могу быть уверен, что они не были в кеше из предыдущего теста. На самом деле, я не знал, что Python кэшируется ... Если бы они были в памяти, не могли бы они вытащить из кеша в цикле? – OldGuyInTheClub
@OldGuyInTheClub:% timeit может запускать функцию несколько раз, что может привести к ускорению при последующих запусках с теми же входами. В отличие от вашего цикла, где каждый раз он имеет разные входные данные, следовательно, кеш не попадает. –