Подтвердить что ты не робот

Неверная производительность кода

Я понимаю, что небезопасный код более подходит для доступа к таким вещам, как API Windows, и делает небезопасные типы отливок, чем писать более эффективный код, но я хотел бы спросить вас, заметили ли вы когда-либо значительное повышение производительности в реальных приложениях используя его по сравнению с безопасным кодом С#.

4b9b3361

Ответ 1

Некоторые измерения производительности

Преимущества производительности не так велики, как вы думаете.

Я сделал некоторые измерения производительности обычного доступа к управляемому массиву против небезопасных указателей на С#.


Результаты выполнения сборки за пределами Visual Studio 2010,.NET 4, используя Любой процессор | Разверните версию на следующей спецификации ПК: x64-based ПК, 1 четырехъядерный процессор. Intel64 Family 6 Model 23 Stepping 10 GenuineIntel ~ 2833 Mhz.

Linear array access
 00:00:07.1053664 for Normal
 00:00:07.1197401 for Unsafe *(p + i)

Linear array access - with pointer increment
 00:00:07.1174493 for Normal
 00:00:10.0015947 for Unsafe (*p++)

Random array access
 00:00:42.5559436 for Normal
 00:00:40.5632554 for Unsafe

Random array access using Parallel.For(), with 4 processors
 00:00:10.6896303 for Normal
 00:00:10.1858376 for Unsafe

Обратите внимание, что небезопасная идиома *(p++) на самом деле работает медленнее. Я предполагаю, что это нарушило оптимизацию компилятора, которая объединяла переменную цикла и доступ к указателю (сгенерированный компилятором) в безопасной версии.

Исходный код доступен на github.

Ответ 2

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

Пример: http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx

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

Ответ 3

Как было указано в других сообщениях, вы можете использовать небезопасный код в очень специализированных контекстах, чтобы получить значительное повышение производительности. Один из этих сценариев - итерация по массивам типов значений. Использование небезопасной арифметики указателя намного быстрее, чем использование обычного шаблона for-loop/indexer.

struct Foo
{
    int a = 1;
    int b = 2;
    int c = 0;
}

Foo[] fooArray = new Foo[100000];

fixed (Foo* foo = fooArray)  // foo now points to the first element in the array...
{
    var remaining = fooArray.length;
    while (remaining-- > 0)
    {
        foo->c = foo->a + foo->b;
        foo++;  // foo now points to the next element in the array...
    }
}

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

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

Ответ 4

Хорошо, я бы предложил прочитать этот блог-пост: Блоги MSDN: Проверка границ массива Исправление в среде CLR

Это разъясняет, как в С# выполняются проверки границ. Более того, тесты Томаса Братца кажутся мне бесполезными (смотря на код), так как JIT удаляет в своих "save" петлях ограничения-так или иначе.

Ответ 5

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

Но из-за скорости его широко используют люди, которые кодируют графику.