2012-02-17 76 views
10

在C#中,将DateTime引用作为参数传递给函数时,是否有任何显着的内存分配减少,而不是按值传递?可以通过在c#中引用DateTime参数来减少内存分配吗?

int GetDayNumber(ref DateTime date) 

VS

int GetDayNumber(DateTime date) 

函数内的代码不修改在任何情况下的日期。

+1

任何你不会使用'date.Day'的理由? – 2012-02-17 11:19:43

+0

有多重要? DateTime对象不完全是内存管理器。它最有可能在堆栈或寄存器中,甚至当你传递一个引用时,你仍然传递的数据(即引用)可能是相同的大小(它不能小得多,因为DateTime很小)。 – 2012-02-17 11:21:57

+0

这个函数的功能与日期不同。日期 这个函数被调用了几百万次,所以它的任何改进都会很棒。我想那么,在堆栈内存分配的差异是“日期时间大小” - “参考大小” – jeroko 2012-02-17 11:28:49

回答

12

A DateTime是一个8字节的结构。 A ref具有4或8个字节,具体取决于您的目标架构。所以最好你会节省4个字节的堆栈内存,这是完全不相关的。

ref甚至可能会阻止某些优化,例如将DateTime放入寄存器,从而实际增加内存使用量。

这是一个明显的过早优化案例。不要这样做。

+0

如果该方法连续被称为百万次,该怎么办?这取决于什么时候为GC解释了参考。如果它是短命的,那么可以,但如果它持续了一个不可忽视的时间,那么参考文献是否会产生积极的影响呢? – 2012-02-17 11:37:37

+1

1)连续100万次根本没有效果。你会得到相同的8个字节一百万次。递归一百万次会是一个问题,但在C#中很少有深度递归函数。 2)GC不会进入这个。分配在堆栈上的本地'DateTime'不需要释放GC。当函数退出时,堆栈指针被调整,并且所有真正的局部变量都消失了。这实际上是免费的。 |如果你的局部变量不是真正的局部变量(lamda capture,async-await,yield iteratiors,...),那么它就变得复杂了,但是在这里并不是这样。 – CodesInChaos 2012-02-17 11:42:31

1

我不认为有任何显着的内存使用减少,但我相信有一些。

当传递的日期时间与裁判也不会有创建了一个新的datetime对象,当你不使用ref关键字

-2

内部,DateTime值表示为蜱的数量,这是一个长期的的64位。

64位处理器将需要相同数量的位来发送变量的地址。

但是,如果在32位处理器中工作,您的地址范围小于日期时间的大小。所以性能可以提高。

但是,在实践中,差异几乎不会被注意到。

+0

这是错误的,它通过值**传递**。即使它是一个引用类型,它不是,它仍然会被传递。 – oleksii 2012-02-17 11:23:55

+1

DateTime是一个结构,所以不通过引用传递 - 除非有人在没有告诉我的情况下更改C#? – 2012-02-17 11:24:02

+2

你是不正确的,DateTime是一个结构,因此通过值传递。 – 2012-02-17 11:24:31

2

与其他类似的问题一样,您需要自己计算时间。几个处理器会发挥重要作用吗?在你的应用程序中,多少字节会占用内存消耗的主要部分?

离开微观优化,首先专注于真正的问题解决。

0

您可以,但是因为DateTime是一个结构体并且只在堆栈上分配,所以开销很小,因为没有类的堆分配。另外,因为该值是作为新实例传递的,所以只要离开该方法,堆栈中的空间就会被释放。

var date = DateTime.Today; // One date time object is allocated and assigned to the stack. 
DoSomething(date); // this will result in a second date time object being allocated and assigned to the stack. 

private void DoSomething(DateTime date) 
{ 
    // do something with the date time object. 
} // As soon as we leave this method, the date time object is removed from the stack as it is now out of scope. 
+2

这不是释放堆栈中的结构的GC。这些只是通过调整函数末尾的堆栈指针来“释放”,所以它们现在处于堆栈的未使用部分。 – CodesInChaos 2012-02-17 11:31:32

+0

好点,我会更新我的回答以反映。 – 2012-02-17 11:34:54