这真的是节省分配吗?

时间:2009-10-29 20:25:11

标签: c#

我在静态实用程序类中有以下内容:

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[] 

11 个答案:

答案 0 :(得分:10)

是的,但你也可以打开一些有趣的副作用。考虑一下:

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

<强>更新
鉴于预期用途(下拉列表中每日的默认数字),您将需要许多(我的意思是许多,如数十万或数百万)此类优化列表有所作为。我不会花时间尝试从内存分配角度优化它;它根本不值得。

现在,我建议你让一个方法返回一个新的int[](公开为IEnumerable<int>),其中包含每次调用的数字。然后,在以后的日子里,如果您碰巧发现这会导致内存或性能出现问题,那么您可以优化该方法。

答案 1 :(得分:6)

是的,这实际上允许您重复使用相同的数组,而不是每次都重新分配一个新数组。

但是,由于您返回的是一个数组(可变),因此无法保证方法的调用者在返回数组后不会修改该数组。返回IEnumerable<T>ReadOnlyCollection<T>会更好,这样您就可以确定除了您之外没有人正在修改集合。 (这与性能无关 - 我认为重要的是指出这一点。)

答案 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

答案 3 :(得分:5)

是的,它只会被创建一次,但要注意,如果任何代码决定修改返回值,那么它将反映给所有其他调用者,因此最好每次都返回一个新副本。或者,您只能公开IEnumerable<int>。您还可以将初始化程序替换为:

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

答案 4 :(得分:4)

您还可以使用Enumerable.Range初始化变量。

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

答案 5 :(得分:3)

每次使用静态变量调用GetListOfAllDaysForMonths时,都会保存分配新数组。什么是不明确的是这是否是对您的代码有价值的变化。该答案在很大程度上取决于您的应用程序中此方法的用例。只有剖析器可以告诉您这是否值得节省。

答案 6 :(得分:2)

即使它有所作为,它也是如此之小,以至于使它完全无关紧要。微优化是没有意义的(除了它们不是很少次,如果你遇到瓶颈,你唯一的方法就是知道它们是什么)。不要让12元素阵列的分配给你带来麻烦,而是专注于算法效率,因为这是你会看到差异的地方。

答案 7 :(得分:1)

为什么优化这个?这是不成熟的,你做这件事的价值可能很小,你永远不会注意到它。如果它确实成为一个问题,那么这就是你优化的时间,这样做是事先浪费时间,资源并且可能使代码变得不必要地复杂和混乱。

答案 8 :(得分:1)

您是否考虑过使用内置的ASP.NET Calendar控件而不是滚动自己的日期选择器?

答案 9 :(得分:0)

如果你不介意调用者可以更改数组并搞砸其他调用者,那么这是一个优化,但在我看来很棘手。

答案 10 :(得分: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)来读取它