|
DateTime.Now is a static property and returns a new instance of a DateTime object. The only thing in memory is the newly allocated (and returned) DateTime object.
Stop over-analyzing this crap and do some real work.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Thanks John,
What is your comments to my original question? There is additional copy, right?
regards,
George
|
|
|
|
|
I suppose, but it's the same as any value type.
|
|
|
|
|
Thanks PIEBALDconsult,
So, you agree with my points (1) and (2) in original question post? And DateTime abc = DateTime.Now statement will create two copies of values?
regards,
George
|
|
|
|
|
Only as far as something like:
public static DateTime
Now
{
get
{
DateTime temp ;
return ( temp ) ;
}
}
(Which may not even be the case.)
In such a method, the value from the local variable gets copied to the receiving variable, so, yes, there are two variables containing the value, but I don't understand why you're asking.
|
|
|
|
|
Thanks PIEBALDconsult,
Question answered. I am just interesting in some techniques, not the real value.
I think understanding of how it works internally will facilitate my grasping of the whole CLR.
regards,
George
|
|
|
|
|
Temporarily yes, but even then it simply does a quadword copy in debug mode; it's very possible .NET optimizes this away in release mode so there is only one struct instance.
The temporary internal instance is required so the property has something to return. But it is discarded (unless optimized away) as soon as the new value is set.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Agree, thanks Joe!
regards,
George
|
|
|
|
|
There are actually several different values created when calling the Now property. The Now property calls UtcNow and ToLocalTime, UtcNow calls GetSystemTimeAsFileTime, ToLocalTime calls TimeZone.CurrentTimeZone.ToLocalTime, et.c.
However, as all those values are value types, the memory is allocated on the stack. The allocation is done when the stack frame is created for each call, and actually doesn't take any extra time at all. So, the only work really done is actually moving the value, which is a single machine instruction.
Despite everything, the person most likely to be fooling you next is yourself.
modified on Tuesday, June 10, 2008 4:43 AM
|
|
|
|
|
Thanks Guffa,
What do you mean "moving the value"? Could you show more description please why value type copy is just "moving the value" please?
regards,
George
|
|
|
|
|
The code "DateTime abc = DateTime.Now;" results in this IL code:
call valuetype DateTime DateTime::get_Now()<br />
stloc.2
The first instruction is the call to the property and second instruction stores the return value from the call into the variable abc. That's all. No extra value, no extra nothing, just a simple call that returns a simple value.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Thanks Guffa,
I think in more details -- the first call will put a new instance on the evaluation stack, and the 2nd call will load the new instance from the evaluation stack into the variable, correct?
regards,
George
|
|
|
|
|
Yes, that is correct, if you by "call" mean "instruction".
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Thanks Guffa!
I understand the operations on stack now. Compared with variable instance on heap, generally speaking why operations on stack is better?
regards,
George
|
|
|
|
|
George_George wrote: Compared with variable instance on heap, generally speaking why operations on stack is better?
Because allocation and deallocation of the memory doesn't cost a thing. The memory is allocated by just making a larger stack frame when the method starts, and deallocation happens when the stack frame is removed. There is no garbage collection involved in freeing the memory.
This of course only applies to value types. Reference types are always allocated on the heap, even if the reference to it is on the stack.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Thanks Guffa,
So, you think GC is the major bottleneck of performance compared with stack variable and heap variable?
regards,
George
|
|
|
|
|
It probably is a waste but you need an instance of the DateTime struct to exist to be able to get the value! The other way would be for the Now property getter to be a method and require an out parameter. This would make things really complicated if you needed to do a simple calculation and didn't need a variable for the Now value.
The overhead is really very small indeed - personally I wouldn't waste my time on such minor details.
Dave
|
|
|
|
|
DaveyM69 wrote: It probably is a waste but you need an instance of the DateTime struct to exist to be able to get the value!
No, the Now property is static, so there is no instance existing before calling the property. The "DateTime" in "DateTime.Now" is just a specification of the class, it's not a value.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Guffa wrote: the Now property is static, so there is no instance existing before calling the property
I understand that. What I meant is the Now property getter returns a new struct of type DateTime
Dave
|
|
|
|
|
Ok, then it sounds like you think that you get the DateTime value from an instance of the DateTime struct, while they are infact the same thing.
It's pretty obvious that you need an instance of DateTime to have an instance of DateTime, if you don't have an instance of DateTime you don't have an instance of DateTime. It's actually so obvious that it sounds silly to say it...
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
I agree - a new instance is created when Now is called. That was the OPs point. It doesn't have to be done that way of course...
public struct ExampleDateTime
{
private int mSomeValue;
public int SomeValue
{
get { return mSomeValue; }
}
public static void Now(out ExampleDateTime outParameter)
{
outParameter.mSomeValue = 1;
}
} could then be used by
ExampleDateTime example = new ExampleDateTime();
ExampleDateTime.Now(out example);
This way only the one ExampleDateTime struct is created.
In DateTime nowDateTime = DateTime.Now; there are two DateTimes, the nowDateTime and the one returned and copied from DateTime.Now.
I agree that it's silly to even think about it (I never would worry about such a thing), but I was just passing my thoughts to the OP.
Dave
|
|
|
|
|
Hi Dave,
Excellent reply! Two more comments,
1.
For out parameter, like outParameter in your sample, even if it is a value type (struct), there is no additional copy, i.e. the instance of ExampleDateTime in function Now is the same as the one we pass into this function (variable example)?
2.
DaveyM69 wrote: there are two DateTimes, the nowDateTime and the one returned and copied from DateTime.Now.
Your above statement is really tricky to understand. Sorry my English is not good, could you express in some other words please?
regards,
George
|
|
|
|
|
Hi George,
Let me begin by saying I'm no expert in the internal workings of the framework or compiler! There are many people here who have a far more in depth knowledge of these things, and if I'm wrong, I'm sure they will point out my errors
As far as I know...
1. There is no additional copy as it works on the actual object passed as a parameter. If there is a copy (I'm not sure how to check), then maybe we could/should force it to be passed by reference?
2. DateTime.Now; returns an instance of the DateTime struct.
DateTime nowDateTime = ... obviously also creates an instance of the DateTime struct.
So now we have two DateTime instances. By DateTime nowDateTime = DateTime.Now; we're simply copying the value of the second to the first.
Obviously you control the lifetime of nowDateTime, I don't know the lifetime of DateTime.Now - I'm still learning too!
Dave
|
|
|
|
|
Hi Dave,
I am confused after reading your reply.
For 1, you mentioned there is no additional copy, for 2, you mentioned there is two copies DateTime.Now and nowDateTime, since we only need nowDateTime, I think the instance returned by DateTime.Now is an additional copy.
Anyway, seems your point 1 and point 2 are conflicting, could you clarify please?
regards,
George
|
|
|
|
|
No additional copy when using the example method with out parameter
Dave
|
|
|
|