Почему строка запускается медленнее, чем в?
Удивительно, но я нахожуstartswith
медленнее, чемin
:
In [10]: s="ABCD"*10
In [11]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 307 ns per loop
In [12]: %timeit "XYZ" in s
10000000 loops, best of 3: 81.7 ns per loop
Как мы все знаем,in
Операция должна искать всю строку иstartswith
просто нужно проверить первые несколько символов, такstartswith
должно быть более эффективным.
когдаs
достаточно большой,startswith
быстрее:
In [13]: s="ABCD"*200
In [14]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 306 ns per loop
In [15]: %timeit "XYZ" in s
1000000 loops, best of 3: 666 ns per loop
Так что кажется, что звонитstartswith
имеет некоторые накладные расходы, что делает его медленным, когда строка мала.
И чем я пытался выяснить, что накладные расходыstartswith
вызов.
Во-первых, я использовалf
переменная, чтобы уменьшить стоимость операции точка - как упоминалось в этомответ - здесь мы можем видетьstartswith
еще медленнее
In [16]: f=s.startswith
In [17]: %timeit f("XYZ")
1000000 loops, best of 3: 270 ns per loop
Далее я проверил стоимость пустого вызова функции:
In [18]: def func(a): pass
In [19]: %timeit func("XYZ")
10000000 loops, best of 3: 106 ns per loop
Независимо от стоимости точечной операции и вызова функции, времяstartswith
составляет около (270-106) = 164 нс, ноin
операция занимает всего 81,7 нс. Кажется, есть еще некоторые накладные расходы дляstartswith
, что это такое?
Добавьте результат теста междуstartswith
а также__contains__
как предложено poke и lvc:
In [28]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 314 ns per loop
In [29]: %timeit s.__contains__("XYZ")
1000000 loops, best of 3: 192 ns per loop