1. Python / Говнокод #6653

    −180

    1. 1
    2. 2
    3. 3
    auto = False
    if self.options.has_key('auto') and self.options['auto']:
        auto = True

    Запостил: frol, 13 Мая 2011

    Комментарии (13) RSS

    • очень осторожный код
      Ответить
      • это называется "к характеристике подошёл очень издалека"... :)
        Ответить
        • Подозреваю, что это просто код, человека, который не знает что у dict, есть get.
          Ответить
    • лоло

      auto = self.options.get('auto') #ftw!
      Ответить
      • Ну это не правильно.
        Правильно: auto = self.option.get('auto', False).
        Ответить
        • Вообще-то, get медленнее даже пары k in d и d[k], но это не тот случай. ;)
          Ответить
          • Хм, не поверил, но действительно медленнее:
            In [3]: %timeit a.get('1', 4)
            1000000 loops, best of 3: 568 ns per loop

            In [4]: %timeit ('1' in a and a['1'])
            1000000 loops, best of 3: 407 ns per loop

            Можете объяснить почему? Или что-то почитать на эту тему?
            Ответить
            • in и [] — операторы, для них опкоды есть, а get — обычный метод. Тут во-первых, затраты на получение атрибута каждый раз (если вынести это за цикл, то значительно ускорится), во-вторых, вызов функции, пусть и встроенной.

              А вот defaultdict (для тех случаев, когда возможно), ещё быстрее — только одна операция.
              $ python -m timeit -s "d={}" "x='auto' in d and d['auto']"
              10000000 loops, best of 3: 0.128 usec per loop
              $ python -m timeit -s "d={}" "x=d.get('auto',False)"
              1000000 loops, best of 3: 0.304 usec per loop
              $ python -m timeit -s "d={};g=d.get" "x=g('auto',False)"
              1000000 loops, best of 3: 0.217 usec per loop
              $ python -m timeit -s "import collections;d=collections.defaultdict(bool)" "x=d['auto']"
              10000000 loops, best of 3: 0.123 usec per loop


              Кстати, никогда не используйте has_key.
              Ответить
              • Да, и следует ещё проверить случай, когда ключ в словаре находится, это существенно.
                $ python -m timeit -n 1000000 -s "d={'auto':True}" "x='auto' in d and d['auto']"
                1000000 loops, best of 3: 0.202 usec per loop
                $ python -m timeit -n 1000000 -s "d={'auto':True}" "x=d.get('auto',False)"
                1000000 loops, best of 3: 0.299 usec per loop
                $ python -m timeit -s "d={'auto':True};g=d.get" "x=g('auto',False)"
                1000000 loops, best of 3: 0.217 usec per loop
                $ python -m timeit -s "import collections;d=collections.defaultdict(bool);d['auto']=True" "x=d['auto']"
                10000000 loops, best of 3: 0.122 usec per loop

                И в этом случае уже может рассматриваться и вариант с try/except.
                $ python -m timeit -s "d={'auto':True}" $'try:x=d["auto"]\nexcept KeyError:x=False'
                10000000 loops, best of 3: 0.154 usec per loop
                $ python -m timeit -s "d={}" $'try:x=d["auto"]\nexcept KeyError:x=False'
                1000000 loops, best of 3: 1.71 usec per loop

                Если ключ обычно есть в словаре, то вариант с исключениями тоже оказывается быстрее get.
                Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий