2013-04-14 3 views
-1

Если объект является неизменным (мой собственный реализованный объект), следует ли использовать свойство для длины или только переменную readonly? Если объект имеет свойство Length as, он теряет часть цикла for for.Свойство длины в неизменяемых объектах

for (int i = 0; i < myObject.Length; i++) // Length is readonly variable 
{ 
    // some code 
} 

и:

int len = myObject.Length; // Length is a property 

for (int i = 0; i < len; i++) 
{ 
    // some code 
} 

Что вы предлагаете?

+1

Вы оценили, что свойство приводит к потере производительности? 'get'ter обычно достаточно просты, чтобы быть встроенным компилятором JIT, поэтому разница между полем и свойством не будет. – dtb

+0

Работа: стирание памяти с использованием байта * с циклом for. Использование переменной из объекта = X ms. Использование свойства = 2 * X ms. Таким образом, свойство намного медленнее. Когда я копирую Length в локальную переменную (из переменной объекта), она дает еще 10% скорости. Поэтому, наконец, я использую свойство Length, а затем скопирую его значение в локальную переменную перед каждым циклом. Конечно, когда я использую long * для очистки этой памяти, будет еще более полезно скопировать длину в локальную переменную. Поэтому я решил это. – zgnilec

ответ

0

Изменение временной переменной для запроса - довольно стандартный рефактор. Другими словами, настоятельно рекомендуется, чтобы, если вызов свойства очень быстр, вам не следует создавать временную переменную. Он называется «replaceTempWithQuery». Вот реклама на нем:

http://www.refactoring.com/catalog/replaceTempWithQuery.html

я настоятельно рекомендую книгу рефакторинга всем, что делает программирование.

Добавление в качестве EDIT: для этого я отказался, но преждевременная оптимизация - это нечто, чего можно избежать - я бы рекомендовал только исправление запроса с помощью temp, если он вызывает очень заметные проблемы.

A famous quote from Donald Knuth: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil". Несмотря на это, это вопрос выбора, если у вас не будет много сопровождающих вашего кода. Тогда время в обслуживании часто оказывает большое влияние на выбор оптимизации/дизайна.

1

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

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

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

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

3

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

Чтобы показать, что я имею в виду, я запустил следующее в режиме Release (если вы оставите его в отладке, он будет работать по-другому).

private int Length { get; set; } 
private int _length; 
void Run() 
{ 
    Length = int.MaxValue; 
    _length = int.MaxValue; 
    var watch = new Stopwatch(); 
    watch.Start(); 
    for (int i = 0; i < Length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
    watch.Restart(); 
    for (int i = 0; i < _length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
} 

Я побежал в 10 раз и получил следующие средние: 743 мс для собственности, 740 мс для переменной. Это различие, вероятно, связано только с небольшим количеством попыток и других вещей, которые происходят на моей машине.

Теперь, если вы отключите вложение с помощью атрибута, вы получите разницу во времени: 4577 мс для свойства и 775 мс для переменной. Теперь это звучит как огромная разница (всего 6 раз больше времени), но помните о моем состоянии цикла: 2 миллиарда итераций. Это означает, что разница была чем-то вроде 2 нс за операцию. Другими словами, около 4 тактов, которых недостаточно, чтобы волноваться во всех, кроме самых экстремальных сценариях производительности.