Так что в этой теме все разговоры, а не цифры, поэтому давайте поговорим о метриках. Я запустил некоторый тестовый код, чтобы получить некоторые показатели производительности с помощью Visual Studio 2010 и
Я получил эти метрики, рассчитав среднее время каждого метода за 10 тестовых прогонов с 10 миллионами итераций каждая в режиме отладки, затем выпуска (не оптимизирован, а оптимизирован):
(Debug)
Метод литья: ~ 32 мс
Метод распределения: ~ 26 мс
(Release)
Метод литья: ~ 20 мс
Метод распределения: ~ 22 мс
Интересно также сравнить эти метрики с аналогичным кодом с управляемым C ++ только с использованием gcnew, и результаты сильно отличаются.
Та же настройка снова. За исключением сравнения метода приведения: "IntPtr ^ ptr = (IntPtr) i;" против метода выделения: "IntPtr ^ ptr = (IntPtr) i;".
(Debug)
Метод литья: ~ 91мс
Метод распределения: ~ 127 мс
(Release)
Метод литья: ~ 22 мс
Метод распределения: ~ 124 мс
Теперь, если вы почесываете голову, говоря, почему C # намного быстрее, чем управляемый C ++, и ответ - нет. Наиболее эффективным способом использования IntPtr является тип значения, а не ссылка на тип значения. Например, вот так: «IntPtr ptr = (IntPtr) i;». Это даст вам ~ 24 мс (больше отладки) или (~ 22 режима выпуска). Посмотрите, как это было оптимизировано выше компилятором, чтобы получить 22 мс, а не 90 мс.
Вывод в C #, если только вы не посмотрите на ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО жесткий код, это не имеет значения. Я думаю, что с моим кодом в Релизе он фактически оптимизировал приведение, потому что комментирование приводило к тому же ~ 22 мс. Но по большей части компилятор поддерживает вас в C #, по крайней мере, в VS 2010. Однако в Managed C ++ / CLI, если вы смотрите на код с минимальными ограничениями производительности, будьте внимательны. Компилятор не будет автоматически оптимизировать распределение gcnew для подхода приведения, и это почти в 6 раз быстрее ... Я фактически столкнулся с этой конкретной проблемой в C ++ / CLI, которая и привела меня к публикации в этой теме при работе с аудио в реальном времени обработка. Мой код (C #): (мой управляемый код на C ++ был очень похож, за исключением того, что мне приходилось самостоятельно писать Average () и использовать для вывода консоль, а не окна сообщений).
static void Main()
{
List<int> castTimings = new List<int>();
List<int> allocTimings = new List<int>();
for (int i = 0; i < TEST_RUNS; ++i)
{
castTimings.Add(RunCastMethod().Milliseconds);
allocTimings.Add(RunAllocationMethod().Milliseconds);
}
MessageBox.Show(string.Format("Casting Method took: {0}ms", castTimings.Average() ));
MessageBox.Show(string.Format("Allocation Method took: {0}ms", allocTimings.Average() ));
}
private static TimeSpan RunAllocationMethod() {
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = new IntPtr(i);
}
return ( DateTime.Now - start );
}
private static TimeSpan RunCastMethod()
{
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = (IntPtr) i;
}
return (DateTime.Now - start);
}