2016-06-24 5 views
-1

Вот мой цикл for. Для выполнения более 100 000 итераций требуется очень много времени.Как сделать цикл более быстрым?

for urlt in xrange(0, len(clean_url_data)): 
    website_title.append(urlt) 
    website_title[urlt]=g.extract(clean_url_data[urlt]).title 
    print urlt 
+2

Я полагаю, что 'g.extract' - это то, что на самом деле требует времени, нет ?! Что оно делает...? – deceze

+0

Уникален ли urlt? – giaosudau

+1

Кажется, что каждая итерация независима, поэтому старайтесь использовать многопроцессорную обработку – galaxyan

ответ

1

Вместо того, чтобы расширить website_title список с помощью website_title.append(urlt), а затем сразу же перезапись, что urlt элемент с данными заголовка, вы должны просто добавить данные заголовка непосредственно в списке.

Кроме того, лучше итерации непосредственно над списком clean_url_data, вместо того, чтобы использовать целочисленный цикл для индекса clean_url_data. Если вам нужен индекс, вы можете использовать enumerate. например:

website_title = [] 
for i, url in enumerate(clean_url_data): 
    website_title.append(g.extract(url).title) 
    print i 

Если вам действительно не нужен этот индекс, вы можете сделать вещи проще. Вот подход, использующий понимание списка, которое немного быстрее, чем использование append в цикле.

website_title = [g.extract(url).title for url in clean_url_data] 

Список постижение использует специальный LIST_APPEND байткод, которая в основном является оператором, так что это быстрее, чем глядя .append метод в списке в то назвав его; вызов функции Python относительно медленный по сравнению с выполнением оператора.

+0

'.append' - это функция, которая пересматривается каждый раз через цикл. Байт-код - хорошая идея, но перед циклом проще добавить 'append = website_title.append', а затем заменить' website_title.append (g.extract (url) .title) 'в цикле' append (g. экстракт (URL) .title) '. Это намного быстрее, так как он не будет повторно оцениваться каждый раз в цикле.Это было сделано из [официальных советов по производительности Python] (https://wiki.python.org/moin/PythonSpeed/PerformanceTips). –

+0

@DavidG. Конечно, кеширование метода .append в локальном, конечно, быстрее, чем выполнение поиска на каждой итерации цикла. Однако это все еще не так быстро, как использование списка. В прошлый раз, когда я тестировал это, версия с кэшированным добавлением была примерно промежуточной по скорости между списком comp и не кэшированной версией, но фактические скорости варьируются в зависимости от версии Python. –

0

Пожалуйста, попробуйте сравнить диапазон(), xrange(), карты(). g.extract может стоить вашего времени.

def set_website_title(urlt): 
    if urlt not in website_title: 
     website_title.append(urlt) 
     website_title[urlt] = g.extract(clean_url_data[urlt]).title 
     print urlt 

if __name__ == "__main__": 
    map(set_website_title, clean_url_data) 
0

Как упоминалось в Галаксиане, для этого можно использовать многопроцессорную обработку. Ниже приведен пример фрагмент кода:

def clean(url): 
    return {'url': url, 'title': g.extract(url).title} 

from multiprocessing import Pool 
pool = Pool() 
website_info = pool.map(clean, clean_url_data) 
0

Вы присоединяя числовой элемент в список website_title, а затем вы перезаписать значение одного и того же элемента в списке. Я не понимаю, как это полезно. Если вы этого не сделаете, цикл for будет немного быстрее.

Поскольку этот тест показывает:

# Your version, with append() and assignment 
%%timeit 
l = [] 
for n in xrange(100000): 
    l.append(n) 
    l[n] = 'something' 

10 петли, лучшие из 3: 22,4 мс на петле

# Without reassignment 
%%timeit 
l = [] 
for n in xrange(100000): 
    l.append('something') 

100 петли, лучшие из 3: 16,6 мс на петле

# even better with list comprehension 
%%timeit 
l = ['something' for n in xrange(100000)] 

100 петель, лучше всего 3: 7.86 мс за петлю

Смежные вопросы