Просить разрешения или извиниться?

Я родом из python, где часто говорят, что извиняться легче, чем спрашивать разрешения. В частности, с учетом двух фрагментов:

if type(A) == int: do_something(A) else: do_something(int(A)) try: do_something(A) except TypeError: do_something(int(A)) 

Затем в большинстве сценариев использования второй будет быстрее, когда A обычно является целым числом (предполагается, что do_something нуждается в целых числах в качестве входных данных и будет быстро увеличивать его исключение), поскольку вы теряете логический тест из каждого цикла выполнения за счет более дорогостоящее исключение, но гораздо реже.

То, что я хотел проверить, было ли это истинно в C #, или же логические тесты достаточно быстрые по сравнению с исключениями, чтобы сделать этот небольшой угловой случай?

О, и меня интересует только производительность релиза, а не отладка.


ОК, мой пример был слишком расплывчатым:

Наивное решение:

 return float(A) % 20 # coerse A to a float so it'll only fail if we actually don't # have anything that can be represented as a real number. 

Логическое решение:

 if isinstance(A, Number): # This is cheaper because we're not creating a new return A % 20 # object unless we really have to. else: return float(A) %20 

Исходное решение:

 try: # Now we're doing any logical tests in the 99% of cases where A is a number return A % 20 except TypeError: return float(A) % 20 

Примеры, использующие FSO, соединения с базой данных или материал по сети, лучше, но немного затянуты для вопроса.

5 Solutions collect form web for “Просить разрешения или извиниться?”

Возможно нет. Исключения .NET относительно дороги.

По этой причине некоторые функции .NET предлагают оба варианта. ( int.TryParse , который возвращает код успеха, часто рекомендуется, потому что он быстрее, чем int.Parse который генерирует исключение при int.Parse )

Но единственный ответ, который имеет значение, – это то, что говорит вам ваше собственное профилирование. Если вам нужна производительность, вам нужно измерить, измерить, измерить.

Поскольку то, что было самым быстрым на моем компьютере, с моим кодом, с моей версией платформы .NET, в настоящее время может быть не самым быстрым на вашем компьютере с вашим кодом с вашей версией платформы .NET в то время, когда вы прочитайте его.

Исключения в .NET довольно тяжелы, поэтому философия на C # заключается в использовании исключений только для исключительных ситуаций, а не для потока программ.

Философия в C # также предназначена для проверки всех входных данных, полученных от внешнего кода, перед использованием. Пример:

 public void Foo(int i) { if (i == 0) // validate input received from external code { throw new ArgumentOutOfRangeException("i"); } DoSomething(i); } public void Foo() { DoSomething(1); } internal void DoSomething(int i) { Debug.Assert(i != 0); // validate that i is not zero in DEBUG build // assume that i is not zero in RELEASE build Console.WriteLine(42 / i); } 

Как правило, я бы сказал, что исключения не должны использоваться для управления потоком. Используйте исключения для исключительных обстоятельств – поэтому, если вы ожидаете, что A будет int, тогда ваш первый подход разумный. Если это может быть int или строка, вторая является более читаемой.

С точки зрения производительности есть разница в выпуске сборки – разумные логические тесты, конечно, достаточно быстр – так что лично я бы пошел на удобочитаемость.

Исключения не должны использоваться в качестве «нормального» средства контроля потока выполнения, и да, они дороги.

В любом случае, я думаю, что ваш вопрос немного ошибочен, исходя из python. C # является (или был?) Статически типизированным языком, что означает, что во время компиляции можно разрешить многие сценарии, подобные тому, что вы предлагаете.

http://paltman.com/2008/01/18/try-except-performance-in-python-a-simple-test/ имеет аналогичный тест, за исключением просмотра has_key, который я ожидаю (слегка) дороже, чем проверка типов.

Для случая большого количества итераций, где ключ существует (поэтому исключение никогда не выбрасывается), оно примерно на 25% быстрее, но все еще довольно быстро. Там, где ключ никогда не существует, он примерно на 1000% медленнее.

Теперь, имея в виду, что проверка типов выполняется быстрее, чем поиск ключа, и что .Net-исключения, как уже упоминалось выше, довольно тяжеловесны, вам понадобится целое число A в большинстве случаев, прежде чем оно даже потенциально окажется полезным.

Но, как упоминалось ранее. Попробуй и посмотри.

  • Передача строки в agege в файле agraph.py. Проблема с networkx и pygraphviz
  • минимальный размер gtk
  • Создание этого кода обработки массива C больше python (и даже numpy)
  • Арифметика высокой точности в Python и / или C / C ++?
  • Как реализовать этот источник C ++ в python?
  • Действительно ли realloc сокращает буферы в общих реализациях?
  • Различия между конструкторами Python и C ++
  • Django или Ruby on Rails
  • Сделать класс C ++ похожим на массив numpy с помощью swig
  • Как я могу использовать valgrind с расширениями Python C ++?
  • Получить число модифицированных строк после выполнения sqlite3
  • Python - лучший язык программирования в мире.