Сохранить память в Python. Как перебрать строки и эффективно их сохранить с помощью файла с 2 миллионами строк? - PullRequest
3 голосов
/ 14 марта 2010

У меня есть файл данных, разделенный табуляцией, с немногим более 2 миллионов строк и 19 столбцов. Вы можете найти его в US.zip: http://download.geonames.org/export/dump/.

Я начал запускать следующее, но с for l in f.readlines(). Я понимаю, что итерация по файлу должна быть более эффективной, поэтому я публикую это ниже. Тем не менее, с этой небольшой оптимизацией я использую 30% своей памяти для процесса и только около 6,5% записей. Похоже, что в этом темпе у него закончится память, как это было раньше. Также у меня очень медленная функция. Что-нибудь очевидное, что я могу сделать, чтобы ускорить это? Поможет ли это del объектам с каждым проходом цикла for?

def run():
    from geonames.models import POI
    f = file('data/US.txt')
    for l in f:
        li = l.split('\t')
        try:
            p = POI()
            p.geonameid = li[0]
            p.name = li[1]
            p.asciiname = li[2]
            p.alternatenames = li[3]
            p.point = "POINT(%s %s)" % (li[5], li[4])
            p.feature_class = li[6]
            p.feature_code = li[7]
            p.country_code = li[8]
            p.ccs2 = li[9]
            p.admin1_code = li[10]
            p.admin2_code = li[11]
            p.admin3_code = li[12]
            p.admin4_code = li[13]
            p.population = li[14]
            p.elevation = li[15]
            p.gtopo30 = li[16]
            p.timezone = li[17]
            p.modification_date = li[18]
            p.save()
        except IndexError:
            pass

if __name__ == "__main__":
    run()

РЕДАКТИРОВАТЬ, Подробнее (по-видимому, важные):

Потребление памяти увеличивается при запуске сценария и сохраняет больше строк. Метод .save () является фальсифицированным методом модели django с фрагментом unique_slug, который записывает в базу данных postgreSQL / postgis.

решено: ведение журнала базы данных отладки в Django пожирает память.

Ответы [ 3 ]

5 голосов
/ 14 марта 2010

Убедитесь, что для параметра Django DEBUG установлено значение False

2 голосов
/ 14 марта 2010

Нет причин для беспокойства в данных, которые вы нам предоставили: увеличивается ли потребление памяти, когда вы читаете все больше и больше строк? * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * курс. Ничего реального нельзя получить, добавив операторы del, поскольку память все равно перерабатывается на каждом участке цикла.

Это может быть ускорено, если есть более быстрый способ заполнения экземпляра POI, чем привязка его атрибутов один за другим - например, передача этих атрибутов (возможно, в качестве аргументов ключевого слова? Positional будет быстрее ...) в конструктор POI , Но так ли это, зависит от того geonames.models модуля, о котором я ничего не знаю, поэтому я могу предложить только очень общий совет - например, если модуль позволяет вам сохранить несколько POI за один прием, а затем сделать их ( скажем) 100 за раз и сохранение их в связках должно привести к ускорению (за счет немного более высокого потребления памяти).

2 голосов
/ 14 марта 2010

Это выглядит прекрасно для меня. Перебирая файл подобным образом или используя xreadlines(), вы будете читать каждую строку по мере необходимости (с разумной буферизацией за кадром). Использование памяти не должно расти, когда вы читаете все больше и больше данных.

Что касается производительности, вы должны профилировать ваше приложение. Скорее всего, узкое место где-то в более глубокой функции, например POI.save().

...