11

In C#, is there any significant reduction in memory allocation when passing a DateTime reference as a parameter to a function as opposed to passing it by value?

int GetDayNumber(ref DateTime date)

vs

int GetDayNumber(DateTime date)

The code inside the function is not modifying the date in any case.

jeroko
  • 418
  • 6
  • 9
  • 1
    Any reason you wouldn't just use `date.Day`? – Ash Burlaczenko Feb 17 '12 at 11:19
  • How significant is significant? A DateTime object isn't exactly a memory hogger. It's most likely going on the stack or in a register anyway, and even when you pass a reference your still passing data (i.e. the reference) which may be the same size (it can't be much smaller since DateTime is tiny). – James Gaunt Feb 17 '12 at 11:21
  • This function does something different than date.Day This function is called millions of times so, any improvement in it, would be great. I guess then, that difference in memory allocation in the stack is the "DateTime size" - "Reference size" – jeroko Feb 17 '12 at 11:28
  • if the code inside the function is not modifying the date then the whole point of passing by reference is deciduous – Mehdi LAMRANI Feb 17 '12 at 11:41
  • @jeroko If it's called often, you want to improve CPU cycles spent, not the space occupied by local variables. The amount of local variables has no direct effect on performance. If you get rid of a local variable of 8 bytes in a non recursive function called a million times, you still get rid only of 8 bytes total, not 8000000 bytes. – CodesInChaos Feb 17 '12 at 11:45

5 Answers5

16

A DateTime is a 8 byte struct. A ref has 4 or 8 bytes depending on your target architecture. So at best you'd save 4 bytes of stack memory, which is completely irrelevant.

It's even likely that ref prevents some optimizations, such as placing the DateTime in a register, thus actually increasing memory use.

This is a clear case of premature optimization. Don't do this.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • What if the method gets called a Million times in a row ? this depends on when is the reference freed for GC. If it's short-lived, ok, but what if it is held for a non-negligible time, wouldn't the ref have a positive effect ? – Mehdi LAMRANI Feb 17 '12 at 11:37
  • 1
    1) A million times in a row would have no effect at all. You'd get the same 8 bytes a million times. A million times recursively would be a problem, but you rarely have deeply recursive function in C#. 2) The GC doesn't come into this. A local `DateTime` allocated on the stack doesn't need the GC to be freed. When the function exits, the stack pointer gets adjusted, and all true local variables are gone. This is practically free. | It only gets complicated if your local variables aren't truly local(lamda capture, async-await, yield iteratiors,...), but that isn't the case here. – CodesInChaos Feb 17 '12 at 11:42
2

As with any other similar question you need to time it yourself. Would a few processor ticks play significant role? Would a few extra bytes play major part in memory consumption in your application?

Leave the micro optimisation and concentrate on real problem solving first.

oleksii
  • 35,458
  • 16
  • 93
  • 163
1

I don't think there's any significant reduction in the memory usage, but I believe there's some.

When passing the datetime with ref there won't be created a new datetime object as when you don't use the ref keyword

f2lollpll
  • 997
  • 6
  • 15
0

You could, however since DateTime is a struct and only allocated on the stack, there is very little overhead as there is no heap allocation like there is for a class. Also because the value is passed as a new instance, the space on the stack will be freed as soon as you leave the method.

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.
Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
  • 2
    It's not the GC that frees structs on the stack. Those are simply "freed" by adjusting the stack pointer at the end of a function, so they are now in the unused part of the stack. – CodesInChaos Feb 17 '12 at 11:31
-1

Internally, DateTime values are represented as the number of ticks, which is a long of 64 bit.

A 64bit processor will need the same amount of bits to send the address of the variable.

But if working in a 32bit processor, your address range is smaller than the size of the datetime. So the performance could be improved.

However, in practice, the difference is nearly never gonna be noticed.

Schiavini
  • 2,869
  • 2
  • 23
  • 49