Здравствуйте, Pavel Dvorkin, Вы писали:
S>>(я что-то не могу себе такой сценарий представить, но пусть будет), PD>Такой сценарий можно себе представить, но не в дотнете. Впрочем, и в дотнете, наверное, можно, если включить unsafe код. Это "истинный" (то есть без реаллокаций) динамический массив.
Не, это уже совсем частный случай. Топикстартер, думаю, оговорил бы этот момент.
Re[5]: На сколько затратно выбрасывание исключения
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>throw из дотнета приводит в конечном счете к вызову нативной RaiseException из KERNELBASE.dll, а она приводит к переключению в режим ядра
D>Кто Вам это сказал ??? RaiseException совершенно не обязана переключаться в kernel mode. В случае 64-битного процессаRaiseException уходит в ядро только при подключенном отладчике, необработанном исключении и тому подобных ситуациях. Обычные же исключения обрабатываются полностью в user mode... Ну или мне счётчики kernel\user time врут...
Я не исключаю, что в x64 что-то изменилось, но хотелось бы более серьезного доказательства, нежели данные счетчиков времени. Если такие доказательства будут, я охотно поменяю свое мнение в том, что касается x64.
Пока что могу лишь сказать, что NtRaiseException как сервис ядра в x64 существует. Вот здесь ее номер даже (в смысле syscall) приведен.
Правда, я не совсем понимаю, что Вы имеете в виду, говоря о необработанном исключении. RaiseException его выбрасывает, а обработка будет потом, если будет. Получается, что если обработки не будет, то управление вернется обратно в RaiseException, чтобы уйти в kernel ? Как-то странно это. Или она сама и должна заниматься обработкой исключения ? Так не ее же это дело, исключения могут и без нее возникнуть вполне. Что-то я не понимаю.
With best regards
Pavel Dvorkin
Re[6]: На сколько затратно выбрасывание исключения
Хм, а как вот это можно объяснить?
Ведь и в том и в другом случае, судя по коду, кидается 1 исключение, но при этом время увеличивается почти в 2 раза?
Re[6]: На сколько затратно выбрасывание исключения
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>но хотелось бы более серьезного доказательства,
Я с большим интересом послушаю эти самые Ваши доказательства. Вы ведь, надеюсь, не забыли, что тезис о переходах в ядро при обычной обработке обычных исключений принадлежит Вам ?
PD>нежели данные счетчиков времени
Лично меня они пока вполне устраивают. Разница с 32-битным процессом WoW64 впечатляет более чем...
PD>Пока что могу лишь сказать, что NtRaiseException как сервис ядра в x64 существует. Вот здесь ее номер даже (в смысле syscall) приведен.
И причём здесь NtRaiseException\ZwRaiseException В приведённом Вами стеке вызовов их нет. Там только RaiseException и RtlRaiseException. Вам напомнить, что означает префикс Rtl ?
Итого, Вы пока не показали вообще ни одного факта перехода в режим ядра
PD>Правда, я не совсем понимаю, что Вы имеете в виду, говоря о необработанном исключении. RaiseException его выбрасывает, а обработка будет потом, если будет
Приехали. А что такое по-Вашему вообще "выбрасывание" ? Сакральный магический акт ?
PD>Получается, что если обработки не будет, то управление вернется обратно в RaiseException,
И когда обработка есть оно туда тоже возвращается. Причём n раз (в данном примере SEH + куча вложенных __finally\__except):
*И эти люди преподают программирование на C\C++
PD>Или она сама и должна заниматься обработкой исключения ?
Совершенно верно...
*Понятно, что не собственно RaiseException, а то что вызывается внутри неё. Основная логика находится в RtlRaiseException и в RtlDispatchException.
PD>Так не ее же это дело, исключения могут и без нее возникнуть вполне.
Что значит "без неё" Нормальное исключение это и есть вызов кого-то из xxxRaiseException. Для "ядерных приветов" имеются оптимизации, которые передают управление сразу на уровень KiUserExceptionDispatch.
PD>Что-то я не понимаю.
Вы очень много чего не понимаете...
Re[5]: На сколько затратно выбрасывание исключения
A>Хм, а как вот это можно объяснить? A>Ведь и в том и в другом случае, судя по коду, кидается 1 исключение, но при этом время увеличивается почти в 2 раза?
Да легко. Для "пустого" стека вызовов сделана какая-нибудь оптимизация по данным. А для размера даже в 1 уже кучу выделений памяти в куче надо делать, например.
Re[4]: На сколько затратно выбрасывание исключения
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Что означает "буфер может переполняться" ? Мы же в управляемом коде. Если это массив и выйти за его границы, то ArrayIndexOutOfBoundsException и так выбросится. Если же что-то иное — хотелось бы знать, что именно.
Буфер это список (List<T>) который имеет ограниченное количество элементов. Надо как-то обработать ситуацию когда использующий его код хочет добавить элемент в буфер когда он уже заполнен.
:)
Re[2]: На сколько затратно выбрасывание исключения
S>Do not use exceptions for normal flow of control. Except for system failures, there should generally be a way to write code that avoids exceptions being thrown.
В общем после прочтения указанных ссылок я сделал вывод, что если речь идет о производительности, то использования исключений нужно избегать. А в остальных случаях все зависит от ситуации.
:)
Re[6]: На сколько затратно выбрасывание исключения
Здравствуйте, drol, Вы писали:
D>Да легко. Для "пустого" стека вызовов сделана какая-нибудь оптимизация по данным. А для размера даже в 1 уже кучу выделений памяти в куче надо делать, например.
Там всё проще, +1 catch-throw
Здравствуйте, drol, Вы писали:
D>Я с большим интересом послушаю эти самые Ваши доказательства. Вы ведь, надеюсь, не забыли, что тезис о переходах в ядро при обычной обработке обычных исключений принадлежит Вам ?
Пожалуйста. Первый рисунок демонстрирует схему выбрасывания и обработки исключения.
D>Итого, Вы пока не показали вообще ни одного факта перехода в режим ядра
См. выше.
PD>>Так не ее же это дело, исключения могут и без нее возникнуть вполне.
D>Что значит "без неё" Нормальное исключение это и есть вызов кого-то из xxxRaiseException.
Именно это и значит. При делении на 0 или access violation происходит исключение процессора, управление передается в ядро минуя вызов RaiseException в user mode. Именно о ней я и писал. Что при этом вызывается в ядре — я не обсуждал.
D>Вы очень много чего не понимаете...
Вынужден на этом дискуссию с Вами прекратить. Я не веду дискуссию с людьми, позволяющими себе агрессивный тон и переход на личности.
With best regards
Pavel Dvorkin
Re[5]: На сколько затратно выбрасывание исключения
Здравствуйте, Cynic, Вы писали:
PD>>Что означает "буфер может переполняться" ? Мы же в управляемом коде. Если это массив и выйти за его границы, то ArrayIndexOutOfBoundsException и так выбросится. Если же что-то иное — хотелось бы знать, что именно.
C>Буфер это список (List<T>) который имеет ограниченное количество элементов. Надо как-то обработать ситуацию когда использующий его код хочет добавить элемент в буфер когда он уже заполнен.
Если это и впрямь System.Collections.Generiс.List, то количество его элементов растет автоматически
If Count already equals Capacity, the capacity of the List<T> is increased by automatically reallocating the internal array, and the existing elements are copied to the new array before the new element is added.
Так что пока не будет OutOfMemoryException — добавляй и ни о чем не думай
With best regards
Pavel Dvorkin
Re[5]: На сколько затратно выбрасывание исключения
Здравствуйте, Cynic, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Что означает "буфер может переполняться" ? Мы же в управляемом коде. Если это массив и выйти за его границы, то ArrayIndexOutOfBoundsException и так выбросится. Если же что-то иное — хотелось бы знать, что именно.
C>Буфер это список (List<T>) который имеет ограниченное количество элементов. Надо как-то обработать ситуацию когда использующий его код хочет добавить элемент в буфер когда он уже заполнен.
Т.е. ограниченность буфера — элемент бизнес-логики? Может, вам что-нибудь вроде циклического буфера подойдет? И почему нельзя просто игнорировать вызов добавления, к примеру?
Re[8]: На сколько затратно выбрасывание исключения
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пожалуйста. Первый рисунок демонстрирует схему выбрасывания и обработки исключения.
И зачем Вы приводите схему десятилетней давности для 32-битных процессов, когда речь уже давно идёт о 64-битных
D>>Что значит "без неё" Нормальное исключение это и есть вызов кого-то из xxxRaiseException.
PD>Именно это и значит. При делении на 0 или access violation происходит исключение процессора, управление передается в ядро минуя вызов RaiseException в user mode
Зачем Вы разговариваете сам с собой ? Было же написано нормальным английско-программистским языком: xxxRaiseException.
D>>Вы очень много чего не понимаете...
PD>Вынужден на этом дискуссию с Вами прекратить. Я не веду дискуссию с людьми, позволяющими себе агрессивный тон и переход на личности.
Странная какая-то у Вас реакция. Вот мне бы на Вашем месте было очень стыдно, что давно не в теме, а студентам втираю. И чтобы как можно быстрее устранить пробелы в своих знаниях я бы использовал все доступные возможности... Жаль Ваших студентов — совсем не повезло им с преподавателем...
Re[7]: На сколько затратно выбрасывание исключения
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Честно говоря, я не ждал, что будет настолько хуже.
Да ненамного хуже SEH вроде
А всё просто: исключения в дотнете заточены под исключительные ситуации (сорри за фиговый каламбур). Если производительность утыкается в стоимость обработки исключений, то проблема уже на 100% не в них самих, а в непродуманной архитектуре / незнании матчасти / неправильно написанном API и тд и тп. Исключений из этого правила на практике не видел.
Ну и разумеется в крайности не надо впадать. Исключения отлично работают для отмены/отката бизнес-операций (кучу понятных оговорок про необходимость отката состояния, побочные эффекты и тд и тп пропустим). А вот писать try-catch вокруг метода проверки заказа — это уже перебор
P.S. Сорри за передоз слова "исключение". Это исключительная ситуация.