Почему словарь занимает меньше времени, чем в Python? - PullRequest
0 голосов
/ 21 января 2019

И словарь, и наборы реализованы как хеш-таблицы в Python и имеют время вставки и время поиска O (1).Я пишу программу для подсчета, если строка состоит из всех уникальных символов, и я использую набор для отслеживания всех символов, увиденных до сих пор.Что я наблюдаю, так это то, что если я использую словарь вместо набора, общее время выполнения программы немного быстрее.Может ли кто-нибудь объяснить мне причину этого?

Код с помощью словаря:

def TestUniqueCharacters(characters):
    chars = {}
    for character in characters:
        if character not in chars:
            chars[character] = 1
        else:
            return False
    return True

for i in range(30000000):
    TestUniqueCharacters("qwertyuiopasdfghjklzxcvbnm1234567890-=[];',.!@#$%^&*()")

Код с использованием набора

def TestUniqueCharacters(characters):
    chars = set()
    for character in characters:
        if character not in chars:
            chars.add(character)
        else:
            return False
    return True

for i in range(30000000):
    TestUniqueCharacters("qwertyuiopasdfghjklzxcvbnm1234567890-=[];',.!@#$%^&*()")

Время выполнения со словарем

Execution time with dictionary

Время выполнения с набором

Execution time with set

1 Ответ

0 голосов
/ 21 января 2019

Я не склонен тратить на это много времени, потому что реализации диктов и наборов различаются в разных версиях Python. Погоня за зависимыми от версии второстепенными загадками не доставляет большого удовольствия; -)

Так что я просто предлагаю изменить:

chars = set()
for character in characters:
    if character not in chars:
        chars.add(character)

до:

chars = set()
charsadd = chars.add   # new line here
for character in characters:
    if character not in chars:
        charsadd(character)  # this line is different - no method lookup now

чтобы увидеть, что происходит под любой версией Python, которую вы используете.

В исходном chars.add(...) каждый раз в цикле необходимо искать метод с именем строки "add" на объекте chars и создавать связанный объект метода, который затем вызывается с аргументом character. Хотя это не основные расходы, это не бесплатно. В предложенном переписывании метод add ищется только один раз, вне цикла.

...