Это действительно экономия?

2

У меня есть следующее в статическом классе 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[] 
  • 1
    Мне действительно любопытно, как это используется ...
  • 3
    Мне интересно, почему этот уровень преждевременной оптимизации так распространен для «управляемых» языков высокого уровня.
Показать ещё 6 комментариев
Теги:

11 ответов

10

Да, но вы также открываете для некоторых интересных побочных эффектов. Рассмотрим это:

int[] a = GetListOfAllDaysForMonths();
a[3] = 200;
int[] b = GetListOfAllDaysForMonths();
Console.WriteLine(b[3]);  // prints 200

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

В настоящее время я бы рекомендовал вам просто вернуть метод new int[] (отображается как IEnumerable<int>) с номерами для каждого вызова. Затем, в более поздний срок, если вам удастся определить это, чтобы создать проблему с памятью или производительностью, вы можете оптимизировать этот метод.

  • 0
    Я обновил свой пост. Я на самом деле сделаю это только для чтения int [] массив.
  • 0
    мы не делаем «после» на производительности. Ненужные распределения - это очевидные сокращения, к которым нужно стремиться, и они автоматически помогают повысить производительность всего приложения.
Показать ещё 2 комментария
6

Да, это позволяет вам повторно использовать один и тот же массив, а не повторно назначать новый каждый раз.

Однако, поскольку вы возвращаете массив (который является изменяемым), вы не можете гарантировать, что вызывающий объект вашего метода не будет изменять массив после его возвращения. Было бы гораздо лучше вернуть IEnumerable<T> или ReadOnlyCollection<T>, чтобы вы могли быть уверены, что никто не модифицирует коллекцию, кроме вы. (Это не имеет ничего общего с производительностью - просто то, что я думал, было бы важно указать).

  • 0
    ну, это массив только для чтения ... он будет использоваться только для заполнения выпадающего списка дней в месяце ... количество дней по умолчанию.
  • 0
    @Coffee: это не только для чтения. Вы просто случайно прочитали это. Там есть важное различие.
Показать ещё 2 комментария
6

Если это действительно так, чтобы заполнить раскрывающийся список, почему бы не использовать метод 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
  • 0
    потому что посмотрите на все жестко закодированные числа, и этот метод должен быть повторно использован на нескольких страницах asp.net.
  • 0
    ваш код очень длинный Все, что мне нужно сделать, это просто связать возвращенный static int [] с моим выпадающим списком, одной строкой кода!
Показать ещё 6 комментариев
5

Да, он будет создан только один раз, хотя имейте в виду, что если какой-либо код решает изменить возвращаемое значение, он будет отражен для всех других вызывающих абонентов, поэтому может быть предпочтительнее возвращать новую копию каждый раз. В качестве альтернативы вы можете вместо этого отобразить IEnumerable<int>. Возможно, вы также можете заменить инициализатор на:

static int[] MonthDays = Enumerable.Range(1, 31).ToArray()

  • 1
    +1 за лучший способ сделать это. Подобные вещи, набираемые вручную, склонны к опечаткам. Путь, путь, способ лучше сделать это процедурно.
  • 0
    Кроме того, его ввод делает ввод данных не программистом.
Показать ещё 6 комментариев
4

Вы также можете инициализировать переменную с помощью Enumerable.Range.

static int[] MonthDays = Enumerable.Range(1, 31).ToArray();
  • 0
    Я бы удалил .ToArray и просто сохранил его как IEnumerable. Вероятно, это лучший способ справиться с этим: никогда не хранить весь массив в памяти.
3

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

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

Даже если это имеет значение, оно настолько мало, что делает его совершенно неуместным. Микрооптимизация бессмысленна (за исключением нескольких раз, когда это не так, единственный способ узнать, что это такое, если вы столкнулись с узкими местами). Не позволяйте выделение 12-элементного массива беспокоить вас, вместо этого сосредоточьтесь на алгоритмической эффективности, потому что именно там вы увидите разницу.

1

Рассматривали ли вы использование встроенного элемента управления ASP.NET Calendar вместо того, чтобы перематывать свой собственный выбор даты?

1

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

0

Если это используется только для заполнения выпадающих списков, то как насчет метода вроде этого:

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) для его чтения

  • 0
    Тьфу, нет. Если вы собираетесь это сделать, вы также можете жестко написать HTML-код для выпадающего списка. Это было бы самой быстрой вещью.
  • 0
    Быстрее, может быть, но много повторного кода. Идеальной вещью будет пользовательский элемент управления со встроенным кодом. Поскольку спрашивающий сказал, что не собирается этого делать, я считаю, что это хороший способ избежать повторения кода с хорошей производительностью (даже если это немного уродливо).
Показать ещё 3 комментария
0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню