2014-02-03 3 views
2

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

Пример кода, в котором он использовал небезопасным:

  unsafe 
      { 
       writeableBmp.CopyPixels(new Int32Rect(1, 0, (int)(width - 1), (int)height - 1), buffer, writeableBmp.BackBufferStride, 0); 
       writeableBmp.Lock(); 
       writeableBmp.WritePixels(new Int32Rect(0, 0, (int)width - 1, (int)height - 1), buffer, writeableBmp.BackBufferStride, 0, 0); 
       writeableBmp.AddDirtyRect(new Int32Rect(0, 0, (int)width - 1, (int)height - 1)); 
       writeableBmp.Unlock(); 
      } 

Его Дело в том, что он где-то читал, что unsafe требуется, и повышает производительность, давая подсказку компилятору, что кусок кода должен быть составлен иначе.

+0

Начать отсчет времени с кодом и без. На разных машинах. Также сравните выходные данные компилятора. Мягко предложите своему коллеге, что предполагаемые оптимизации никогда не должны делаться без доказательств для их поддержки. Разве ваш коллега измерил разницу? –

+2

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

+0

В целом ключевые слова C# и языковые конструкции передают их намерения очень хорошо. Просто взглянув на слово «небезопасное», можно предположить, что код пытается сделать что-то вне управляемой области. Что, черт возьми, так небезопасно в написании пикселей для крика вслух? – Alex

ответ

3

Ну в соответствии с http://msdn.microsoft.com/en-us/library/t2yzs44b.aspx небезопасный создает только небезопасный контекст. Это необходимо только при использовании арифметики указателей и т. Д., Которая считается небезопасной и поэтому необходимо создать небезопасный контекст.

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

Профилируйте код с или без него или проверьте MSIL, чтобы это доказать.

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

Некоторого подход к нему:

using System.Threading.Tasks; 
using System.Xml; 
using System.Xml.Linq; 
using System.Xml.Serialization; 

namespace CSharpTestbench 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      int x = 42; 
      if (x == 42) 
      { 
       Console.WriteLine("it is 42"); 
      } 
     } 
    } 
} 

Смотрит в не оптимизированном коде MSIL таким образом:

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  30 (0x1e) 
    .maxstack 2 
    .locals init ([0] int32 x, 
      [1] bool CS$4$0000) 
    IL_0000: nop 
    IL_0001: ldc.i4.s 42 
    IL_0003: stloc.0 
    IL_0004: ldloc.0 
    IL_0005: ldc.i4.s 42 
    IL_0007: ceq 
    IL_0009: ldc.i4.0 
    IL_000a: ceq 
    IL_000c: stloc.1 
    IL_000d: ldloc.1 
    IL_000e: brtrue.s IL_001d 
    IL_0010: nop 
    IL_0011: ldstr  "it is 42" 
    IL_0016: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001b: nop 
    IL_001c: nop 
    IL_001d: ret 
} // end of method Program::Main 

Украшать его с небезопасным результатом в:

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  32 (0x20) 
    .maxstack 2 
    .locals init ([0] int32 x, 
      [1] bool CS$4$0000) 
    IL_0000: nop 
    IL_0001: nop 
    IL_0002: ldc.i4.s 42 
    IL_0004: stloc.0 
    IL_0005: ldloc.0 
    IL_0006: ldc.i4.s 42 
    IL_0008: ceq 
    IL_000a: ldc.i4.0 
    IL_000b: ceq 
    IL_000d: stloc.1 
    IL_000e: ldloc.1 
    IL_000f: brtrue.s IL_001e 
    IL_0011: nop 
    IL_0012: ldstr  "it is 42" 
    IL_0017: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001c: nop 
    IL_001d: nop 
    IL_001e: nop 
    IL_001f: ret 
} // end of method Program::Main 

Оба скомпилированных с/небезопасным, конечно. На самом деле у небезопасного кода есть больше инструкций, которые дают в несколько более крупном исполняемом файле, но должны быть пренебрежимыми. Небезопасные вызовы просто заменяются инструкцией NOPCIL, которая буквально «ничего не делает» ожидает увеличения размера исполняемого файла (http://en.wikipedia.org/wiki/List_of_CIL_instructions).

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

R # также говорит, что это не нужно.

Какое доказательство имеет разработчик, поддерживающий это требование?

+0

Что действительно имеет значение - это код, который работает. Что делает дрожание с IL? –

+0

@ Профилирование Давида Хеффернана было также моим первым догадком, но мне было просто любопытно «MSIL». Я не знаю, как дрожание относится к серии кодов «nop». Я думаю, вы, вероятно, не заметите какой-либо разницы, поскольку любой завернутый код, такой как пиксели копий и т. Д., Накладывает удар по производительности и замечание 'nop' вряд ли будет возможно. За исключением некоторых массивных циклов для построенного сценария. – Samuel

+0

Большое спасибо! Я думаю, что это именно то доказательство, в котором я нуждался – Archeg

3

Вот ваша ссылка: http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize

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

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

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

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

Смежные вопросы