Под C #, какой удар по производительности - блок try, throw и catch

Chrome

Chrome (версия 38 с момента написания) имеет 3 способа определить тип MIME и делает это в определенном порядке. Ниже приведен фрагмент из файла src/net/base/mime_util.cc, метода MimeUtil::GetMimeTypeFromExtensionHelper.

// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type.  That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

Жестко кодированные списки идут немного раньше в файле: https://cs.chromium.org /chromium/src/net/base/mime_util.cc?l=170 (kPrimaryMappings и kSecondaryMappings).

Пример: при загрузке CSV-файла из системы Windows с Microsoft Excel установлен, Chrome сообщит об этом как application/vnd.ms-excel. Это связано с тем, что .csv не указан в первом жестко запрограммированном списке, поэтому браузер возвращается в системный реестр. HKEY_CLASSES_ROOT\.csv имеет значение с именем Content Type, которое установлено на application/vnd.ms-excel.

Internet Explorer

Снова используя тот же пример, браузер сообщит application/vnd.ms-excel. Я думаю, что разумно предположить, что Internet Explorer (версия 11 по записи) использует реестр. Возможно, он также использует жесткий список, такой как Chrome и Firefox, но его закрытая природа источника затрудняет проверку.

Firefox

Как указано в коде Chrome, Firefox (версия 32 с момента написания) работает аналогичным образом. Фрагмент из файла uriloader\exthandler\nsExternalHelperAppService.cpp, метод nsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

Жестко закодированные списки появляются раньше в файле, где-то рядом с линией 441. Вы ищете defaultMimeEntries и extraMimeEntries.

С моим текущим профилем браузер сообщает text/csv, потому что в нем есть запись в mimeTypes.rdf (пункт 2 в списке выше). С новым профилем, который не имеет этой записи, браузер сообщает application/vnd.ms-excel (пункт 3 в списке).

Резюме

Жестко кодированные списки в браузерах довольно ограничены. Часто тип MIME, отправленный браузером, будет сообщен ОС. И именно поэтому, как указано в вопросе, тип MIME, о котором сообщает браузер, является ненадежным.

13
задан Noah 5 March 2009 в 19:57
поделиться

8 ответов

Бросок (а не выгода) является дорогим.

не вставляют блок выгоды, если Вы не собираетесь сделать что-то полезное (т.е. преобразовать в более полезное исключение, обработайте ошибку).

Просто перебросок исключения (оператор броска без аргумента) или, еще хуже, бросает тот же объект, как просто поймано определенно неправильная вещь.

РЕДАКТИРОВАНИЕ: избегать неоднозначности:

Перебросок:

catch (SomeException) {
  throw;
}

Создают исключение из предыдущего объекта исключения, где все время выполнения, обеспеченное состояние (особенно отслеживание стека), перезаписывается:

catch (SomeException e) {
  throw e;
}

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

catch (SomeException e) {
  throw new SomeException(e.Message);
}

, который теряет почти всю полезную информацию состояния e содержавший (включая то, что было первоначально брошено.)

10
ответ дан Richard 6 March 2009 в 05:57
поделиться

Это - плохой дизайн под любым языком.

Исключение разработано, чтобы быть пойманным на уровне, который можно иметь дело с ними. Ловля исключения, только для броска его снова является просто бессмысленной пустой тратой времени (это также заставляет Вас терять ценную информацию о местоположении исходной ошибки).

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

кроме того, обратите внимание, что исключения для исключительные случаи. Вещь, которая должна никогда , происходит. Они не должны привыкнуть на месте к нормальной проверке законности (т.е. не ловите исключение деления на нуль; проверьте, чтобы видеть, является ли делитель нулем заранее).

14
ответ дан James Curran 6 March 2009 в 05:57
поделиться

В целом выдача исключения является дорогостоящей в.NET. Просто наличие блока попытки/выгоды/наконец не. Так, да, существующий код плох с точки зрения производительности, потому что, когда он действительно бросает, он выдает 5-6 чрезмерно увеличенных в размерах исключений, не добавляя значения просто разрешение исходному исключению, естественно пузырьковому 5-6 стековых фреймов.

Хуже все же, существующий код действительно плох с точки зрения дизайна. Одно из основных преимуществ обработки исключений (по сравнению с возвратом кодов ошибки) - то, что Вы не должны проверять на исключения/коды возврата везде (в стеке вызовов). Вы должны только поймать их в небольшом количестве мест, которые Вы на самом деле хотите к дескриптор их. Игнорирование исключения (в отличие от игнорирования кода возврата) не игнорирует или скрывает проблему. Это просто означает, что это будет обработано выше стек вызовов.

2
ответ дан C. Dragon 76 6 March 2009 в 05:57
поделиться

Согласно msdn:Performance Подсказки и Приемы , который можно использовать, пытаются поймать без любой проблемы производительности до реального occure броска.

14
ответ дан Avram 6 March 2009 в 05:57
поделиться

Попробуйте / Выгода / Бросок является медленным - лучшая реализация должна была бы проверить значение прежде, чем поймать его, но если Вы, которых не может продолжить absolutly, Вы - более обеспеченный бросок и ловля только, когда это рассчитывает. Проверка и вход более эффективны иначе.

1
ответ дан Fry 6 March 2009 в 05:57
поделиться

Если каждый слой стека просто повторно бросает тот же тип с той же информацией, не добавляя ничто нового, то это абсолютно абсурдно.

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

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

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

0
ответ дан Daniel Earwicker 6 March 2009 в 05:57
поделиться

Это не ужасно в и себя, но нужно действительно следить за вложением.

приемлемый вариант использования как таков:

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

catch(IOException ex)
{
    throw new PlatformException("some additional context", ex);
}

Теперь это позволяет потребителю делать:

try
{
    component.TryThing();
}
catch(PlatformException ex)
{
   // handle error
}

Да, я знаю, что некоторые люди скажут, но потребитель должен поймать IOException, но это зависит от того, насколько абстрактный код потребления на самом деле. Что, если Impl сохраняет на диск что-то и потребителя, не имеет никакой допустимой причины думать, что их операция коснется диска? В таком сценарии не имело бы никакого смысла помещать эту обработку исключений в код потребления.

то, Чего мы обычно стараемся избегать при помощи этого шаблона, помещает "всеобъемлющий" обработчик исключений в код бизнес-логики, потому что мы хотим узнать все возможные типы исключений, поскольку они могли бы привести к более фундаментальной проблеме, которая должна быть исследована. Если мы не ловим, это пузырится, поражает "лучший лучший" обработчик уровней, и должен останавливать приложение от движения дальше. Это означает, что клиент будет отчет, что исключение и Вы получите шанс изучить его. Это важно, когда Вы пытаетесь создать устойчивое программное обеспечение. Необходимо найти все эти ошибочные случаи и написать определенный код для обработки их.

то, Что не очень симпатично, является вложением они чрезмерная сумма, и это - проблема, которую необходимо решить с этим кодом.

, Поскольку другой плакат указал, что исключения для довольно исключительного поведения, но не берут это слишком далеко. В основном код должен выразить "нормальную" операцию, и исключения должны решить потенциальные проблемы, с которыми можно столкнуться.

С точки зрения исключений производительности прекрасны, Вы получите ужасные результаты, если Вы тест перфекта с отладчиком к встроенному устройству, но в выпуске без отладчика они на самом деле довольно быстры.

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

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

В точном примере, который Вы даете, я не уверен все же. Мне кажется, что никакая выгода действительно не получена от обертывания, что, кажется, универсальное tcl исключение в другом универсальном звучании tcl исключение. Если что-либо, что я предложил бы разыскать исходного создателя кода и изучить, существует ли какая-то конкретная логика позади его взглядов. Возможности состоят в том, хотя это Вы могли просто уничтожить выгоду.

2
ответ дан Quibblesome 6 March 2009 в 05:57
поделиться

Исключения являются медленными, пытаются не использовать их.

Видят ответ, который я дал здесь .

В основном, Chris Brumme (кто был в команде CLR) сказал, что они реализованы как исключения SEH, таким образом, Вы получаете большой удар, когда они брошены, должны получить штрафы, поскольку они пузырятся через стек OS. Это действительно превосходная статья и идет подробно в том, что происходит, когда Вы выдаете исключение. например:

<час>

, Конечно, самая большая стоимость исключений - при фактическом броске того. I’ll возвращают этой близости конец блога.

<час>

Производительность. Исключения имеют прямые затраты, когда Вы на самом деле бросаете и ловите исключение. У них может также быть косвенная стоимость, связанная с продвижением обработчиков на записи метода. И у них может часто быть коварная стоимость путем ограничения codegen возможностей.

<час>

Однако существует серьезная долгосрочная проблема производительности за исключениями, и это должно быть включено в Ваше решение.

Рассматривают некоторые вещи, которые происходят, когда Вы выдаете исключение:

  • Захват отслеживание стека путем интерпретации метаданных, испускаемых компилятором для руководства нашего стека, раскручиваются.

  • Пробегает цепочку обработчиков стек, называя каждый обработчик дважды.

  • Компенсируют несоответствия между SEH, C++ и организованными исключениями.

  • Выделяют управляемый экземпляр Исключения и выполняют его конструктора. Скорее всего, это включает ищущие ресурсы для различных сообщений об ошибках.

  • , Вероятно, предпринимают путешествие через ядро ОС. Часто берите аппаратное исключение.

  • Уведомляют любые приложенные отладчики, профилировщиков, векторные обработчики исключений и другие заинтересованные стороны.

Это - световые годы далеко от возврата-1 от Вашего вызова функции. Исключения являются по сути нелокальными, и если there’s очевидная и устойчивая тенденция для today’s архитектуры, it’s, что необходимо остаться локальными для хорошей производительности.

Некоторые люди будут утверждать, что исключения не являются проблемой, не имеют никаких проблем производительности и обычно являются хорошей вещью. Эти люди получают много голосов избирателей, но они просто неправы. Я видел, что штат Microsoft предъявляет те же претензии (обычно с техническими знаниями, обычно резервируемыми для маркетингового отдела), но нижняя строка из первых уст состоит в том, чтобы использовать их экономно.

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

-1
ответ дан Community 6 March 2009 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: