Форум сайта python.su
Пытался проверить время выполнения с трай\эксептом и без него - результат почти идентичный. так ли это всегда?
Офлайн
да.
Офлайн
Читаю сейчас “Эффективное использование С++” Скотта Майерса. Как я понял оттуда, оператор try в C++ действительно на порядок медленнее, чем простая проверка с помощью if (которая в 2-3 процессорных команды транслируется).
А на Питоне это обычный оператор, равноправный со всеми другими.
Офлайн
в питоне используется оптимизация try-except, согласно которой в случае возникновения исключения ветвь кода except будет раскручиваться довольно медленно. т.е. расплачиваться придется за обработку исключения, чтобы сделать эту конструкцию относительно дешевой по времени для большинства случаев (исходим из предположения, что исключения – это редкое явление).
Офлайн
да. ветвь except получается примерно в 5-10 раз тормознее ветви else
Отредактировано (Май 27, 2008 11:39:34)
Офлайн
from timeit import Timer
def f1():
try:
v = ValueError(“ZZZ”)
raise v
except:
pass
def f2():
try:
v = ValueError(“ZZZ”)
return v
except:
pass
t1 = Timer('f1()', ‘from __main__ import f1’)
print t1.timeit()
t2 = Timer('f2()', ‘from __main__ import f2’)
print t2.timeit()
Подставьте в f1 и f2 тот код, который считаете нужным. Разница все равно в разы. Но для обработки ошибок все равно нужно использовать именно исключения.
P.S. Мейерс - отличный автор. Рекомендую еще Саттера и Александреску.
Офлайн
А стоит ли заводить кучу своих исключений, повязанных на бизнес-логику (ну и райзить их по мере возникновения) или все же стоит делать для них другую обработку?
Просто возникает желание повесить на самом верху try/except, причем в одном эксепте ловить внутренние ошибки приложения, а во втором - все остальные. Так по идее меньше кода, и, если ошибка критическая (которая блокирует процесс) - вроде правильно. Но вот если ошибка не критическая, и ее можно обработать и продолжать процесс, стоит ли в этом случае ставить try/except, или лучше проверку, и раизить варнинги (ну или другой путь)?
Офлайн
Хороший вопрос. Я тоже не знаю правильно ли это, но я примерно так и делаю.
Завожу несколько своих исключений, и на разных уровнях обрабатываю.
IMHO это позволяет убрать кучу разных проверок (если например ошибка передается наверх через много функций), и вообще делает код проще.
Отредактировано (Май 28, 2008 12:53:11)
Офлайн
Способ правильный. По другому - больше кода и потенциальных необработанных ошибок
Офлайн
ну а в случае некритических ошибок? ведь если ошибка некритична, для работы приложения, теоретически эта ветка может отрабатывать довольно часто, и тогда это может быть накладно (в плане времени), но с другой стороны, это должно быть направлено скорее на улучшение качества кода (что бы такие ошибки в последствии не возникали.
from traceback import print_exc
def one():
out = None
try:
get_smth()
except:
print_exc()
out = ‘default’
return out
def two():
out = get_smth()
if not out:
out = ‘default’
return out
В первом случае мы хэндлим все ошибки в топ левеле, таким образом мы имеем возможно исправить все баги в get_smth() (который сам будет сетапить ‘default’ в итоге).
Во втором случае мы вынуждены дебажить get_smth() до победного конца (добавляя кучу проверок и т.п), и все равно, в случае ошибки приложение вылетит, хотя ошибка не критичная.
Т.е. теоретически, первый способ предпочтительнее (ну по-крайней мере безопаснее), но если во втором грамотно организовать проверки, таким образом что бы ошибки исключить - то все будет ок.
и вообще, стоит ли на это обращать внимание, или клепать try/except где только можно?
Офлайн