l [:] проблема с производительностью - PullRequest
1 голос
/ 21 января 2011

Недавно я отлаживал код, подобный следующему

def getList():
    #query db and return a list
    total_list = Model.objects.all()
    result = list()
    for item in total_list:
        if item.attr1:
            result.append(item)
    return result


# in main code    
org_list = getList()
list = orgList[:]#this line cause cpu problems.

if len(org_list)>0 and org_list[0].is_special:
    my_item = org_list[0]

for i in list:
    print_item(i)

doSomethingelse(list[0])

Чтобы упростить код, я изменяю большую его часть, но основная часть здесь.

В методе getList мы запрашиваем dbи получить 20 ~ 30 строк.Затем мы создаем список Python из него и возвращаем его.в основном методе мы получаем переменную org_list из метода getList и нарезаем ее с помощью orgList [:]

, зацикливаем этот список и вызываем специальные элементы в нем, например list [0]

что этот код работает на очень занятом сервере и, к сожалению, он использует большую часть процессора и в конечном итоге блокирует наши серверы.Проблема здесь в том, что мы нарезаем список varibale с помощью list [:], если мы этого не делаем и просто используем переменную org_list, вместо этого у наших серверов проблем нет.Есть ли у кого-нибудь идеи, почему это может произойти?это нарезка использует много процессора или когда мы используем нарезанный список.он использует много процессора?

Ответы [ 4 ]

2 голосов
/ 22 января 2011

Код, который вы показываете, будет работать в течение 0,1 микросекунды, которые потребуются для создания исключения:

org_list = getList()
list = orgList[:]#this line cause cpu problems.

orgList должно быть org_list. Покажите минимальный код, который действительно воспроизводит проблему.

Кроме того, это убивает встроенную функцию list. Не делай этого.

Обновление Еще одна мысль: распространенный ответ: «Приложение Django работает медленно!» "отключить флаг отладки" ... очевидно, он не освобождает память в режиме отладки.

Update2 about "" "Я обнаружил, что когда вы нарезаете список. Он фактически работает как представление этого списка и просто вызывает методы оригинального списка, чтобы получить фактический элемент." "" Откуда вы получить эту идею? Этого не может быть в случае с простым старым списком! Вы переопределили list где-нибудь?

В вашей getList функции:

(1) положить в print type(list)

(2) замените result = list() на result = [] и посмотрите, исчезнет ли проблема.

0 голосов
/ 22 января 2011

К сожалению, фактический код является собственностью компании, в которой я работал, поэтому я не могу дать его в точности так, как есть, но вот некоторая его часть (имена переменных изменены, но аргумент метода mainTree действительно был назван list.)

    mainObj = get_object_or_404(MainObj, code_name=my_code_name)
    if (not mainObj.is_now()) and (not request.user.is_staff):
        return HttpResponseRedirect("/")

    main_tree = mainObj.main_tree()
    objects = main_tree[:] # !!!
    if objects.__len__() == 1 and not objects[0].has_special_page:
        my_code_name = objects[0].code_name

...
...
...

mainObj.main_tree() is the following

    def main_tree(self):
        def append_obj_recursive(list, obj):
            list.append(obj)
            for c in self.obj_set.filter(parent_obj=obj):
                append_obj_recursive(list, c)
            return list

        root_obj = self.get_or_create_root_obj();
        top_level_objs = self.obj_set.filter(parent_obj=root_obj).order_by("weight")
        objs = []

        for tlc in top_level_objs:
            append_obj_recursive(objs, tlc)
        return objs

Это действительно странная проблема. нарезка не должна вызывать такую ​​причудливую проблему. Если я смогу найти ответ, я также опубликую его здесь.

0 голосов
/ 22 января 2011

Хотелось бы узнать:

  • что тип total_list ?Пожалуйста, сделайте тип печати (total_list)

  • , какие типы элементов total_list ?

  • Имеете ли вы представление о размерах этих элементов?

  • Какое количество элементов в списке возвращается getList () ?20-30?

Замечания:

- давать ключевое слово "список" в качестве имени для списка не очень хорошая идея (в list =orgList [:] )

-ваш getList можно записать функцию:

def getList():
    #query db and return a list
    total_list = Model.objects.all()
    return [ item for item in total_list if item.attr1 ]
0 голосов
/ 22 января 2011

list = org_list[:] делает копию org_list. Обычно вы видите что-то подобное, когда вам нужно изменить список, но вы также хотите сохранить оригинал.

Код, который вы показываете мне, не похоже, что он на самом деле изменяет org_list, и если doSomethingelse(list[0]) не изменяет список, я не понимаю, почему он на самом деле копируется. Даже если он действительно изменяет list, поскольку после этих нескольких строк кода org_list не требуется, вы, вероятно, можете обойтись просто с помощью org_list и без копирования фрагмента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...