У меня есть следующее в статическом классе Utility:
static int[] MonthDays = new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
public static int[] GetListOfAllDaysForMonths()
{
return MonthDays;
}
Насколько это эффективно в этом случае, вызывая GetListOfAllDaysForMonths() в нескольких местах в коде, я сохраняю себя от необходимости выделять и создавать новый int [] каждый раз, когда этот метод вызывается?
Обновлено: Позволяет сделать это только для чтения
static readonly int[]
Да, но вы также открываете для некоторых интересных побочных эффектов. Рассмотрим это:
int[] a = GetListOfAllDaysForMonths();
a[3] = 200;
int[] b = GetListOfAllDaysForMonths();
Console.WriteLine(b[3]); // prints 200
Обновление
Учитывая предполагаемое использование (номера по умолчанию для числа дней в раскрывающихся списках), вам понадобится много (и я имею в виду многие, как и сотни тысяч или миллионы) такие списки для такого рода оптимизации, чтобы иметь значение. Я бы не тратил время на оптимизацию этого с точки зрения распределения памяти; это просто не стоит того.
В настоящее время я бы рекомендовал вам просто вернуть метод new int[]
(отображается как IEnumerable<int>
) с номерами для каждого вызова. Затем, в более поздний срок, если вам удастся определить это, чтобы создать проблему с памятью или производительностью, вы можете оптимизировать этот метод.
Да, это позволяет вам повторно использовать один и тот же массив, а не повторно назначать новый каждый раз.
Однако, поскольку вы возвращаете массив (который является изменяемым), вы не можете гарантировать, что вызывающий объект вашего метода не будет изменять массив после его возвращения. Было бы гораздо лучше вернуть IEnumerable<T>
или ReadOnlyCollection<T>
, чтобы вы могли быть уверены, что никто не модифицирует коллекцию, кроме вы. (Это не имеет ничего общего с производительностью - просто то, что я думал, было бы важно указать).
Если это действительно так, чтобы заполнить раскрывающийся список, почему бы не использовать метод DateTime DaysInMonth
, чтобы получить количество дней, указанных в году и месяц, затем создайте массив, содержащий эти значения (используя Enumerable.Range или некоторые такие), чтобы заполнить выпадающее меню?
DateTime.DaysInMonth(2009, 10); // returns 31
DateTime.DaysInMonth(2009, 2); // returns 28
DateTime.DaysInMonth(2012, 2); // returns 29
DateTime.DaysInMonth(2009, 9); // returns 30
Да, он будет создан только один раз, хотя имейте в виду, что если какой-либо код решает изменить возвращаемое значение, он будет отражен для всех других вызывающих абонентов, поэтому может быть предпочтительнее возвращать новую копию каждый раз. В качестве альтернативы вы можете вместо этого отобразить IEnumerable<int>
. Возможно, вы также можете заменить инициализатор на:
static int[] MonthDays = Enumerable.Range(1, 31).ToArray()
Вы также можете инициализировать переменную с помощью Enumerable.Range.
static int[] MonthDays = Enumerable.Range(1, 31).ToArray();
Верно, что вы сохраните выделение нового массива каждый раз, когда вызывается GetListOfAllDaysForMonths, используя статическую переменную. Какой неоднозначной является то, является ли это целесообразным изменением для вашего кода. Этот ответ сильно зависит от вариантов использования этого метода в вашем приложении. Только профилировщик может сказать вам, стоит ли экономить.
Даже если это имеет значение, оно настолько мало, что делает его совершенно неуместным. Микрооптимизация бессмысленна (за исключением нескольких раз, когда это не так, единственный способ узнать, что это такое, если вы столкнулись с узкими местами). Не позволяйте выделение 12-элементного массива беспокоить вас, вместо этого сосредоточьтесь на алгоритмической эффективности, потому что именно там вы увидите разницу.
Рассматривали ли вы использование встроенного элемента управления ASP.NET Calendar вместо того, чтобы перематывать свой собственный выбор даты?
зачем оптимизировать это? это преждевременно, ценность, которую вы получаете от этого, вероятно, настолько мала, что вы ее никогда не заметите. Если это когда-либо стало проблемой, тогда это время, когда вы оптимизируете это, прежде чем рука будет пустой тратой времени, ресурсом и может сделать код излишне сложным и беспорядочным.
Если это используется только для заполнения выпадающих списков, то как насчет метода вроде этого:
populateDaysList(ListItemsCollection items) {
items.Add(new ListItem("1"));
items.Add(new ListItem("2"));
items.Add(new ListItem("3"));
...
items.Add(new ListItem("31"));
}
Нет необходимости в массиве или итераторе (for или foreach) для его чтения
Если вы не возражаете, что вызывающие могут изменить массив и испортить другие вызывающие, то это оптимизация, но сложная, на мой взгляд.