Объем и производительность переменных

Ниже приведен код, который я использую

private void TestFunction()
{
  foreach (MySampleClass c in dictSampleClass)
  {
    String sText = c.VAR1 + c.VAR2 + c.VAR3
    PerformSomeTask(sText,c.VAR4);
  }
}

Мой друг предложил изменить (для повышения производительности dictSampleClass - словарь. Он имеет объекты 10K)

private void TestFunction()
{
  String sText="";
  foreach (MySampleClass c in dictSampleClass)
  {
    sText = c.VAR1 + c.VAR2 + c.VAR3
    PerformSomeTask(sText,c.VAR4);
  }
}

Мой вопрос: "Улучшает ли производительность выше производительность, если да, как?"

WOW это более ожидаемый ответ. Большинство парней сказали, что "компилятор С# позаботится об этом". Так что насчет c компилятора?

Ответ 1

У компилятора есть интеллект для перемещения объявлений переменных в/из циклов, где это необходимо. Однако в вашем примере вы используете строку, которая неизменна. Объявляя это снаружи, я считаю, что вы пытаетесь "создать один раз, использовать много", однако строки создаются каждый раз, когда они изменяются, поэтому вы не можете этого достичь.

Не звучать harse, но это преждевременная оптимизация и, вероятно, неудачная - из-за неизменности строки.

Если коллекция велика, сходите по пути добавления многих строк в StringBuilder, разделенных разделителем. Затем разделите строку на этом разделителе и итерации массива, чтобы добавить их, вместо того, чтобы их конкатенировать и добавить в один цикл.

StringBuilder sb = new StringBuilder();

foreach (MySampleClass c in dictSampleClass)
{
    sb.Append(c.VAR1);
    sb.Append(c.VAR2);
    sb.Append(c.VAR3);
    sb.Append("|");
}

string[] results = sb.ToString().Split('|');

for (int i = 0; i < dictSampleClass.Count; i++)
{
    string s = results[i];
    MySampleClass c = dictSampleClass[i];
    PerformSomeTask(s,c.VAR4); 
}

Я не вижу никаких преимуществ при использовании этого кода - скорее всего, даже не работает!

UPDATE: в свете быстрой производительности создания строк из нескольких строк, если PerformSomeTask является вашим узким местом, попробуйте разбить итерацию строк на несколько потоков - это не улучшит эффективность кода, но вы сможете использовать несколько ядер.

Ответ 2

Запустите две функции через отражатель и посмотрите на сгенерированную сборку. Это может дать некоторую информацию, но в лучшем случае производительность не будет минимальной.

Ответ 3

Вместо этого я бы пошел на это:

private void TestFunction() 
{ 
  foreach (MySampleClass c in dictSampleClass) 
  { 
    PerformSomeTask(c.VAR1 + c.VAR2 + c.VAR3, c.VAR4); 
  } 
} 

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

Ответ 4

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

Всегда используйте код, который повышает читаемость.

Вы можете проверить это, разобрав программу.

Ответ 5

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