Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Что предпочесть: int x = arr.Lenth + strText.Append(x) или strText.Append(arr.Lenth)?

#c_sharp


Что предпочесть для вывода длины массива:

передать в переменную int x = arr.Lenth, и уже потом сделать strText.Append(x);

или обойтись без промежуточных этапов: strText.Append(arr.Lenth);



Проблема, если правильно понимаю, связана с уничтожением объектов сборщиком мусора.
В первом случае в памяти останется только переменная х, во-втором - до момента вывода
arr.Length массив будет находится в памяти. 
Или нет?
    


Ответы

Ответ 1



Вы бы сперва обозначили скоупы, в которых у вас находятся arr и вызов strText.Append(). Предположим, они находятся внутри одно скоупа. Есть один важный постулат о работе сборщика мусора: Время сборки объектов недетерминировано и зависит от реализации CLR Этому есть куча причин, в которые для ответа вдаваться не нужно. Главное, что из этого постулата вытекает следующее: все потуги рассудить, какой вариант лучше, в общем-то бесполезны. void Foo() { int arr = new int[5]; int x = arr.Length; // какой-то длинный код strText.Append(x); // в этом месте память из-под arr еще может быть не освобождена! } Десктопная CLR, как правило, убирает объекты еще до выхода из скоупа, как только они становятся не нужны, поэтому теоретически переменная x имеет смысл. Если переменные arr и вызов strText.Append() находятся в разных скоупах, время между заполнением массива и вызовом метода сильно неопределенное и на момент вызова метода массив уже давно не нужен, тогда сохранение длины массива тоже теоретически имеет смысл. Чуть больший, чем в первом случае :). Почему теоретически? Во всех рассуждения об оптимизациях нужно руководствоваться только практикой. Как говорил классик: "Преждевременная оптимизация -- корень всех зол". Поэтому подобные вещи стоит принимать во внимание только когда "припрет": приложение начнет потреблять много памяти, процесс начнет много времени проводить в GC и т.д. Вот тогда берем в руки профайлер, смотрим на неоптимальные участки кода и вносим исправления. А до тех пор подобные вопросы имеют чисто теоретическую направленность.

Ответ 2



1) На всех семинарах по C# неоднократно говорилось, что код вида: int x = 3; int y = x * 2; оптимизатором превращается в код int y = 3 * 2; выбрасывая х вообще. 2) Давайте подумаем логически. Код int x = arr.Length; // какой-то длинный код, очень, очень, очень длинный код, на 1 500 000 строк strText.Append(x); зачем оптимизатору держать в памяти, все 1 500 000 строк кода, переменную х? Если он это может вычислить в нужной точке strText.Append(arr.Length); Вариант, когда внутри этих 1 500 000 строчек кода меняется длина arr не рассматривается, потому-что хранение переменной x тогда вообще не имеет смысла. 3) Конструкция типа int x = arr.Length; // какой-то длинный код strText.Append(x); имеет право быть, в режиме Debug если Вам нужно посмотреть что происходит с длиной массива (х). В режиме Release оптимизатор ее выбросит (х). P.S. А чего Вы так боитесь сборщика мусора? У меня была прога, которая обрабатывала 90 000 000 записей базы и работала всю ночь каждый день. И ни разу сборщик ничего нужного не удалил...

Ответ 3



передать в переменную int x = arr.Lenth, и уже потом сделать strText.Append(x); Это имеет смысл делать только если массив достаточно большой (не пару тысяч элементов, а действительно большой). есть код код между int x = arr.Lenth и strText.Append(x); который выполняется достаточно долго (не пол секунды, а действительно долго). Во всех остальных случаях - не будет никакой ощутимой разницы, делайте как вам удобнее.

Комментариев нет:

Отправить комментарий