Я пытаюсь использовать модуль timeit в Python (EDIT: мы используем Python 3), чтобы выбирать между несколькими различными потоками кода. В нашем коде у нас есть серия операторов if, которые проверяют наличие кода символа в строке, и если он есть, заменяют его следующим образом:
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
Мы делаем это несколько раз для разных подстрок. Мы спорим между этим и использованием только такой замены:
str_var = str_var.replace("<substring>", "<new_substring>")
Мы попытались использовать timeit, чтобы определить, какой из них быстрее. Если первый кодовый блок выше — «stmt1», а второй — «stmt2», наша строка установки выглядит так:
str_var = '<string><substring><more_string>',
наши операторы timeit будут выглядеть так:
timeit.timeit(stmt=stmt1, setup=setup)
а также
timeit.timeit(stmt=stmt2, setup=setup)
Теперь, запустив его просто так, на 2 наших ноутбуках (такое же оборудование, аналогичная вычислительная нагрузка) stmt1 (оператор с оператором if) работает быстрее даже после нескольких запусков (3-4 сотых секунды против около четверти). секунды для stmt2).
Однако, если мы определим функции для выполнения обеих задач (включая настройку создания переменной) следующим образом:
def foo():
str_var = '<string><substring><more_string>'
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
а также
def foo2():
str_var = '<string><substring><more_string>'
str_var = str_var.replace("<substring>", "<new_substring>")
и запустить timeit как:
timeit.timeit("foo()", setup="from __main__ import foo")
timeit.timeit("foo2()", setup="from __main__ import foo2")
оператор без оператора if (foo2) работает быстрее, что противоречит неработающим результатам.
Мы что-то упускаем из того, как работает Timeit? Или как Python справляется с подобным случаем?
редактируйте здесь наш фактический код:
>>> def foo():
s = "hi 1 2 3"
s = s.replace('1','5')
>>> def foo2():
s = "hi 1 2 3"
if '1' in s:
s = s.replace('1','5')
>>> timeit.timeit(foo, "from __main__ import foo")
0.4094226634183542
>>> timeit.timeit(foo2, "from __main__ import foo2")
0.4815539780738618
против этого кода:
>>> timeit.timeit("""s = s.replace("1","5")""", setup="s = 'hi 1 2 3'")
0.18738432400277816
>>> timeit.timeit("""if '1' in s: s = s.replace('1','5')""", setup="s = 'hi 1 2 3'")
0.02985000199987553
foo
, метод оператораif
всегда составляет около 0,06, а метод безif
— около 0,3. Когда я использую функцииfoo
, то в этом случае метод оператораif
составляет около 0,61, а метод безif
— около 0,53. (Это средства использованияtimeit
10 раз для каждой из четырех возможностей.) Я использую довольно быстрый настольный компьютер, используя IPython с Python 2.7.3. - person ely   schedule 07.01.2014foo2
по-прежнему занимает больше времени, хотя разница гораздо меньше (0,311 дляfoo
против 0,326 дляfoo2
). - person CraigularB   schedule 07.01.2014if
вообще короче. На самом деле он выполняет больше работы, чемreplace
, поскольку тестif
являетсяTrue
(поэтомуreplace
выполняется в обоих случаях). Единственный способ, которымif
может сэкономить ваше время, — это если строка не содержит строку для замены, тем самым экономя ваше время на самом вызовеreplace
, и это должно быть правдой только в том случае, еслиin
имеет более быстрый порядок времени, чемreplace
. Я не знаю, почему это будет иметь большое значение, но вы используете другую строку для замены в не-функции с версиейif
. - person jpmc26   schedule 07.01.2014