2009-06-04 3 views
4

Интересно, какой самый эффективный способ назначения строковых переменных в цикле. Так, например, если я должен просматривать список узлов и присвоения значения узла в строку, было бы лучше, если бы я определить переменную перед цикл начинается какC# Лучший способ присвоения значений строкам в цикле

string myStringVariable = string.Empty 
foreach(XmlNode node in givenNodes) 
{ 
    myStringVariable = node.Value; 
    .... 
    ... 
} 

или это будет более эффективным, если я определить переменную внутри цикла, как

foreach(XmlNode node in givenNodes) 
{ 
    string myStringVariable = node.Value; 
    .... 
    ... 
} 

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

Спасибо за ответы.

+0

Возможно, вы можете отформатировать части исходного кода в своем вопросе. Отметьте его и используйте «Ctrl + K» или кнопку образца кода. – crauscher

ответ

1

Нет, нет реальной разницы в производительности между ними. VM признает, что ему нужно только выделить пространство в стеке для одной дополнительной переменной.

13

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

+0

Извините, вы, кажется, правы! (Удалено голосование) У меня есть тенденция всегда забывать о оптимизации компилятора ... – Noldorin

+0

Без обид. –

1

Обычно я не оптимизирую этот уровень, потому что я ожидал, что компилятор JIT сможет выполнять такую ​​оптимизацию в любом случае во время выполнения. Сказав это, я никогда не сравнивал этих двух. Конечно, если вам действительно нужна максимальная производительность, стоит проверить ее в обоих направлениях (используя достаточное количество итераций и с помощью сборки релиза).

6

Я предполагаю, что главный вопрос: нужно ли использовать эту строковую переменную дальше в вашем коде где-нибудь или ее использование ограничено областью цикла for? Если он ограничен областью цикла for, определенно объявите его внутри цикла. Я сомневаюсь, что есть какое-то ограничение производительности для этого в любом случае, но это должно быть второстепенным для правильной работы ваших переменных.

1

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

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Diagnostics; 

namespace stringtestloop 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Stopwatch w = new Stopwatch(); 
      int itterations = 1024 * 1024 * 512; 

      w.Start(); 
      string var1 = string.Empty; 
      for (var i = 0; i < itterations; i++) 
      { 
       var1 = "some string"; 
      } 
      w.Stop(); 

      Console.WriteLine("outside: {0} ms", w.ElapsedMilliseconds); 

      w.Reset(); 

      w.Start(); 
      for (var i = 0; i < itterations; i++) 
      { 
       string var2 = "some string"; 
      } 
      w.Stop(); 

      Console.WriteLine("inside: {0} ms", w.ElapsedMilliseconds); 
      Console.ReadKey(); 
     } 
    } 
} 

EDIT:

Следующий вопрос спросить себя ... Это 536870912 (1024 * 1024 * 512) аналогичное число, что вы собираетесь работать с. Если нет, если ваш номер будет намного меньше, вы действительно не заметите разницы.

+0

Cheers Greg, Я вижу разницу в производительности, используя ваш код. При объявлении снаружи он принимает около 1500 мс, когда внутри он принимает около 2000 мс. –

+1

Возможно, вы захотите дважды проверить бенчмаркинг, Хамид. Как и Грег, я получаю очень похожие результаты. Также обратите внимание, что если вы скомпилируете этот выпуск, он оптимизирует тело цикла. –

0

Я сомневаюсь, что существует значительная разница в производительности, поскольку в обоих случаях вы просто получаете ссылку на XmlNode.Value, не создавая новую строку.

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

1

В связи с тем, что строки неизменяемы, а .net работает со ссылками, разница между этими методами не отличается.

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

И последнее, но не менее важное значение имеет различие в сфере охвата. Поэтому объявите переменную в соответствующей области, где требуется переменная.

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