Второе, вероятно, будет почти наверняка незначительно быстрее, потому что логически здесь задействовано меньшее количество заданий.В первом случае код фактически эквивалентен:
MyClass tmp = new MyClass()
tmp.Id = 1;
tmp.Code = "Test";
MyClass c = tmp;
Вполне возможно, что JIT-компилятор исключит их, когда вы объявляете переменную new - это не будетбыть в состоянии сделать это, если вы присваиваете существующую переменную с инициализатором объекта.
РЕДАКТИРОВАТЬ: я только что попытался скомпилировать с включенной оптимизацией и без нее, и в этом случае "новой переменной" компилятор C #исключает два , если оптимизирует.Это не иначе (но JIT все еще мог).В случае «переназначения» это может иметь заметное значение, поэтому я не ожидаю такой же оптимизации.Хотя я не проверял.
Я был бы очень удивлен, увидев ситуацию, когда это действительно имело существенное значение, поэтому я бы выбрал более читаемый вариант, который является IMO первым.
РЕДАКТИРОВАТЬ: Я думал, что люди могут быть заинтересованы в тесте, показывающий, что это имеет значение.Это намеренно ужасный код, который замедляет скрытое дополнительное присваивание - я создал большую изменчивую структуру.Urgh.В любом случае ...
using System;
using System.Diagnostics;
struct BigStruct
{
public int value;
#pragma warning disable 0169
decimal a1, a2, a3, a4, a5, a6, a7, a8;
decimal b1, b2, b3, b4, b5, b6, b7, b8;
decimal c1, c2, c3, c4, c5, c6, c7, c8;
decimal d1, d2, d3, d4, d5, d6, d7, d8;
#pragma warning restore 0169
}
class Test
{
const int Iterations = 10000000;
static void Main()
{
Time(NewVariableObjectInitializer);
Time(ExistingVariableObjectInitializer);
Time(NewVariableDirectSetting);
Time(ExistingVariableDirectSetting);
}
static void Time(Func<int> action)
{
Stopwatch stopwatch = Stopwatch.StartNew();
action();
stopwatch.Stop();
Console.WriteLine("{0}: {1}ms",
action.Method.Name,
stopwatch.ElapsedMilliseconds);
}
static int NewVariableObjectInitializer()
{
int total = 0;
for (int i = 0; i < Iterations; i++)
{
BigStruct b = new BigStruct { value = i };
total += b.value;
}
return total;
}
static int ExistingVariableObjectInitializer()
{
int total = 0;
BigStruct b;
for (int i = 0; i < Iterations; i++)
{
b = new BigStruct { value = i };
total += b.value;
}
return total;
}
static int NewVariableDirectSetting()
{
int total = 0;
for (int i = 0; i < Iterations; i++)
{
BigStruct b = new BigStruct();
b.value = i;
total += b.value;
}
return total;
}
static int ExistingVariableDirectSetting()
{
int total = 0;
BigStruct b;
for (int i = 0; i < Iterations; i++)
{
b = new BigStruct();
b.value = i;
total += b.value;
}
return total;
}
}
Результаты (с / o + / debug -):
NewVariableObjectInitializer: 3328ms
ExistingVariableObjectInitializer: 3300ms
NewVariableDirectSetting: 1464ms
ExistingVariableDirectSetting: 1491ms
Я несколько удивлен тем, что версия NewVariableObjectInitializer медленнее, чем версии с прямой установкой ..похоже, что компилятор C # не оптимизирует этот случай так, как это делается для ссылочных типов.Я подозреваю, что есть некоторые тонкости вокруг типов значений, которые мешают этому.