Я знаю, что исключения имеют штраф за производительность, и что обычно более эффективно пытаться избегать исключений, чем бросать большой try/catch во всем - но как насчет самого блока try ? Какова стоимость простого объявления try/catch, даже если он никогда не вызывает исключение?Производительность «Попробуйте» на C#
ответ
Эксплуатационная стоимость попытки очень маленькая. Основная стоимость обработки исключений - это получение трассировки стека и других метаданных, и это затраты, которые не выплачиваются, пока вам не придется бросать исключение.
Но это будет зависеть от языка и реализации. Почему бы не написать простую петлю на C# и не занять ее самостоятельно?
Да. Попробуйте бесплатно, потому что в основном его обрабатывают метаданные, которые действительно проверяются только тогда, когда исключение действительно выбрано. –
Возможно, вы захотите ознакомиться с обработкой структурированных исключений. Это реализация исключений Window и используется в .NET.
Общее высказывание, что исключения являются дорогостоящими, когда они пойманы - не бросили. Это связано с тем, что большинство сбора метаданных исключений (например, получение трассировки стека и т. Д.) Действительно происходит только на стороне try-catch (а не на стороне броска).
Развертывание стека на самом деле довольно быстро - CLR поднимает стек вызовов и только обращает внимание на блоки, которые он находит; ни в коем случае в чистом блоке try-finally во время выполнения попытка «завершить» исключение (это метаданные и т. д.).
Из того, что я помню, любые попытки уловов с фильтрами (такие как «catch (FooException) {}») так же дороги, даже если они ничего не делают с исключением.
Я бы рискнул сказать, что метод (назовем его CatchesAndRethrows) со следующим блоком:
try
{
ThrowsAnException();
}
catch
{
throw;
}
может привести к более быстрому стека блуждания в методе - такие, как:
try
{
CatchesAndRethrows();
}
catch (Exception ex) // The runtime has already done most of the work.
{
// Some fancy logic
}
Некоторые номера:
With: 0.13905ms
Without: 0.096ms
Percent difference: 144%
Вот эта контрольная отметка, которую я запускал (помните, что режим выпуска - работать без deb UG):
static void Main(string[] args)
{
Stopwatch withCatch = new Stopwatch();
Stopwatch withoutCatch = new Stopwatch();
int iterations = 20000;
for (int i = 0; i < iterations; i++)
{
if (i % 100 == 0)
{
Console.Write("{0}%", 100 * i/iterations);
Console.CursorLeft = 0;
Console.CursorTop = 0;
}
CatchIt(withCatch, withoutCatch);
}
Console.WriteLine("With: {0}ms", ((float)(withCatch.ElapsedMilliseconds))/iterations);
Console.WriteLine("Without: {0}ms", ((float)(withoutCatch.ElapsedMilliseconds))/iterations);
Console.WriteLine("Percent difference: {0}%", 100 * withCatch.ElapsedMilliseconds/withoutCatch.ElapsedMilliseconds);
Console.ReadKey(true);
}
static void CatchIt(Stopwatch withCatch, Stopwatch withoutCatch)
{
withCatch.Start();
try
{
FinallyIt(withoutCatch);
}
catch
{
}
withCatch.Stop();
}
static void FinallyIt(Stopwatch withoutCatch)
{
try
{
withoutCatch.Start();
ThrowIt(withoutCatch);
}
finally
{
withoutCatch.Stop();
}
}
private static void ThrowIt(Stopwatch withoutCatch)
{
throw new NotImplementedException();
}
Я думаю, что ОП спросил о влиянии производительности, когда исключения НЕ выбрасываются. – Shimmy
На самом деле, пару месяцев назад я создания веб-приложений ASP.NET, и я случайно завернул попробовать/поймать блок с очень длинной петлей. Несмотря на то, что цикл не генерировал никаких исключений, потребовалось слишком много времени для завершения. Когда я вернулся и увидел try/catch, завернутый в цикл, я сделал это наоборот, я завернул цикл в блок try/catch. Производительность улучшилась. Вы можете попробовать это самостоятельно: сделайте что-нибудь наподобие
int total;
DateTime startTime = DateTime.Now;
for(int i = 0; i < 20000; i++)
{
try
{
total += i;
}
catch
{
// nothing to catch;
}
}
Console.Write((DateTime.Now - startTime).ToString());
И затем выньте блок try/catch. Вы увидите большую разницу!
Хммм. Я просто попробовал это на .Net 2.0 (используя «Секундомер»). 50000 испытаний 20000 циклов итераций занимает 4184 мс без 'try-catch', 4363ms с' try-catch'. Это невероятно маленькая разница. Такая разница будет еще менее заметна, если каждая итерация фактически выполняет что-то помимо простой операции добавления. Я ударил аналогичные результаты с и без отладки. – Brian
Чтобы увидеть, что действительно стоит, вы можете запустить код, указанный ниже. Он принимает простой двухмерный массив и генерирует случайные координаты, которые находятся за пределами допустимого диапазона. Если ваше исключение происходит только один раз, конечно, вы его не заметите. Мой пример делается для того, чтобы подчеркнуть, что это будет означать, когда вы делаете это несколько тысяч раз, и то, что поймает исключение против внедрения простого теста, спасет вас.
const int size = 1000;
const int maxSteps = 100000;
var randomSeed = (int)(DateTime.UtcNow - new DateTime(1970,1,1,0,0,0).ToLocalTime()).TotalMilliseconds;
var random = new Random(randomSeed);
var numOutOfRange = 0;
var grid = new int[size,size];
var stopwatch = new Stopwatch();
Console.WriteLine("---Start test with exception---");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < maxSteps; i++)
{
int coord = random.Next(0, size * 2);
try
{
grid[coord, coord] = 1;
}
catch (IndexOutOfRangeException)
{
numOutOfRange++;
}
}
stopwatch.Stop();
Console.WriteLine("Time used: " + stopwatch.ElapsedMilliseconds + "ms, Number out of range: " + numOutOfRange);
Console.WriteLine("---End test with exception---");
random = new Random(randomSeed);
stopwatch.Reset();
Console.WriteLine("---Start test without exception---");
numOutOfRange = 0;
stopwatch.Start();
for (int i = 0; i < maxSteps; i++)
{
int coord = random.Next(0, size * 2);
if (coord >= grid.GetLength(0) || coord >= grid.GetLength(1))
{
numOutOfRange++;
continue;
}
grid[coord, coord] = 1;
}
stopwatch.Stop();
Console.WriteLine("Time used: " + stopwatch.ElapsedMilliseconds + "ms, Number out of range: " + numOutOfRange);
Console.WriteLine("---End test without exception---");
Console.ReadLine();
Пример вывода этого кода:
---Start test with exception---
Time used: 3228ms, Number out of range: 49795
---End test with exception---
---Start test without exception---
Time used: 3ms, Number out of range: 49795
---End test without exception---
- 1. попробуйте поймать за производительность C#
- 2. Попробуйте, оператор catch в C#
- 3. ошибки/исключения (попробуйте-задвижка) C#
- 4. Попробуйте обработать исключение исключения C++
- 5. Влияние Dalvik на производительность на языке C++?
- 6. Производительность на сетях codding
- 7. попробуйте и рогатки/попробуйте + отличия?
- 8. Производительность приложения WPF C#
- 9. Обмен памятью C - Производительность
- 10. Как улучшить производительность этого кода на C++?
- 11. У макросов на C++ улучшена производительность?
- 12. лучший способ проверить производительность кода на C#
- 13. C 64-разрядная производительность цикла на x86
- 14. Производительность size_t в C++
- 15. C# Производительность Выпуск
- 16. C++: Попробуйте поймать на строительстве класса с константным членом
- 17. .Net vs C++ (производительность)
- 18. Невозможно объяснить производительность C++
- 19. Производительность сериализации C++
- 20. Производительность Python C API?
- 21. Производительность фильтра исключения C#
- 22. C++ производительность кода
- 23. C++ Малая производительность объекта
- 24. C# маркерные структуры производительность
- 25. C# каталога производительность сканирования
- 26. C# - Производительность combobox
- 27. C++ производительность вложенного цикла
- 28. Производительность штраф в C++
- 29. . Производительность на виртуальных машинах
- 30. X12 Reader (C#) Производительность
Вы единственный человек, который может ответить на этот вопрос. Вы единственный человек, который знает, какое оборудование и программное обеспечение вы используете, вы единственный человек, который знает, какие показатели производительности имеют отношение к вашему клиенту, и так далее. Напишите некоторые реалистичные тесты, попробуйте их на реалистичном оборудовании, и тогда вы узнаете ответ. Любой, кто пытается ответить на ваш вопрос, либо догадывается, либо описывает характеристики производительности на своих машинах для своих клиентов, а не ваших. В любом случае, это не те данные, которые вам нужны. –
@ Эрик - Хорошо сказано. –