Найти - Пользователи
Полная версия: Работа со словарем, какой вариант быстрее?
Начало » Python для новичков » Работа со словарем, какой вариант быстрее?
1 2
Alala
Возник с коллегой спор, какой вариант работает быстрее:
1)
a = {'a':[0, 1], 'b':[1, 1], c:[1, 0]}
for x in a:
megafunction(x, a[x][0], a[x][1])
2)
a = {'a':[0, 1], 'b':[1, 1], c:[1, 0]}
for x,y in a.iteritems():
megafunction(x, y[0], y[1])
есть какие-то преимущества одного варианта над другим?
truporez
Вот на таком тесте итератор работает чуть быстрее

#!/usr/bin/env python 
#-*- coding: UTF-8 -*-

import cProfile

a = dict( (i, [i&1, i&2]) for i in xrange(5000000) )
megafunction = lambda a, b, c: a+b-c

def test1():
for x in a:
megafunction(x, a[x][0], a[x][1])

def test2():
for x,y in a.iteritems():
megafunction(x, y[0], y[1])

cProfile.run("test1()")
cProfile.run("test2()")
Fibio
на самом деле тестила несколько раз простые циклы, map и генераторы списков, простые циклы всегда чуть медленнее, а вот map и генераторы дают неоднозначные результаты, даже при выполнении одного и того же выражения (ф-ции), хотя Лутц утверждает что генераторы быстрее. В Вашем варианте преимуществ имхо нет.
Alala
truporez
Ок, спасибо!
я как-то не догадалась тупо протестить это)))

Вообще, конечно, хотелось бы понять разницу в устройстве
Enchantner
Alala
их имеет смысл сравнивать только на больших объемах данных. Попробуй сгенерировать словарь на пару тысяч значений и отпрофилируй.

Я так понимаю, что в случае iteritems() всё должно быть эффективнее, потому что с помощью for'а ты как бы приделываешь итератор снаружи к объекту и при этом хранишь его в памяти. Во втором же случае объект сам предоставляет тебе свой интерфейс итератора, который может быть оптимизирован изнутри и который хранит в памяти по умолчанию только один объект одновременно.
o7412369815963
1-ый вариант медленнее из за того что там на каждой итерации дваждый идет выборка из словаря по ключу x
Enchantner
o7412369815963
Не аргумент. Во втором выборка дважды идёт из списка, и то и то выполняется за O(1).
o7412369815963
Enchantner
o7412369815963
Не аргумент. Во втором выборка дважды идёт из списка, и то и то выполняется за O(1).
1) Сравните поиск по ключу в словаре из 5М элементов, и выборка из листа в 2 элемента.
2) В 1 варианте выборки из списка что-ли нет?
bw
Второй, очевидно, должен быть быстрее; и можно пойти дальше:
>>> for x, (y0, y1) in a.iteritems():

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

..bw
Enchantner
o7412369815963
1) Сравните поиск по ключу в словаре из 5М элементов, и выборка из листа в 2 элемента.
Товарищ, вы знаете, что такое O(1)? Это значит, что выборка из контейнера в общем случае не зависит от количества элементов в нём. В основе списка лежит массив, выборка по индексу (указателю). В основе словаря - хэш-таблица, в которой выборка может затормаживаться коллизиями, которые вряд ли присутствуют в наборе из нескольких элементов.

Но да, согласен, в первом случае идёт двойная выборка.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB