Q. re object/string creation

  • Thread starter Thread starter Lee Jackson
  • Start date Start date
L

Lee Jackson

Whats the difference between the following in terms of how the CLR
allocates and garbage collects? Which is better in terms of memory
usage/performance?

a)
foreach (string strURL in arrLongListOfURLs) {
string strCopy = strURL;
}


b)
string strCopy;
foreach (string strURL in arrLongListOfURLs) {
strCopy = strURL;
}

And if the same logic was used with an HttpWebRequest
e.g.

httpWebRequest = (HttpWebRequest)WebRequest.Create (strURL);

is there anything extra to consider (apart from closing the response
and stream)?


Thanks
 
Those two constructs results in *exactly* the same IL on my box
(.NET1.1). So there is no difference.

/Joakim
 
Lee said:
Whats the difference between the following in terms of how the CLR
allocates and garbage collects? Which is better in terms of memory
usage/performance?

a)
foreach (string strURL in arrLongListOfURLs) {
string strCopy = strURL;
}


b)
string strCopy;
foreach (string strURL in arrLongListOfURLs) {
strCopy = strURL;
}

And if the same logic was used with an HttpWebRequest
e.g.

httpWebRequest = (HttpWebRequest)WebRequest.Create (strURL);

is there anything extra to consider (apart from closing the response
and stream)?


Thanks

Hi,

as stated before, the exact same IL is produced for the two constructs.
It's up to the jitter to decide where the reference 'strCopy' will be
stored. As 'strCopy' is a local variable, it will be kept on the
thread's stack (most likely), or maybe in a register (less likely).
It's also up to the jitter to decide how many stack locations are
necessary throughout the execution of the method. Say you have 100
local variables, but only one of them is used at any point in time,
actually one stack location will be used (and reused). (I'm simplifying
things here to state my point). Or the jitter might decide to give
every local variable its own private location on the stack. No one
actually knows (without digging any deeper). Conclusion, you don't need
to worry about this.
So, assigning 'strUrl' to 'strCpy' declared inside or outside the loop
doesn't make any difference.

Cheers,
Benoit
 
Hi,

as stated before, the exact same IL is produced for the two constructs.
It's up to the jitter to decide where the reference 'strCopy' will be
stored. As 'strCopy' is a local variable, it will be kept on the
thread's stack (most likely), or maybe in a register (less likely).
It's also up to the jitter to decide how many stack locations are
necessary throughout the execution of the method. Say you have 100
local variables, but only one of them is used at any point in time,
actually one stack location will be used (and reused). (I'm simplifying
things here to state my point). Or the jitter might decide to give
every local variable its own private location on the stack. No one
actually knows (without digging any deeper). Conclusion, you don't need
to worry about this.
So, assigning 'strUrl' to 'strCpy' declared inside or outside the loop
doesn't make any difference.

Cheers,
Benoit

Thanks for the (great) explanation :)

Still worried though ;)
 
Lee said:
Thanks for the (great) explanation :)

Still worried though ;)

Hi,

Worried about what, if I may ask ? The number of local variables used
throughout the method should be the least of your concerns. Stack space
does not have to be garbage collected, and it grows and shrinks
automatically when entering and leaving methods. It doesn't matter if
your method uses 10, 20 or even 100 local variables. Complexity with
regard to space and time are negligable.
Declaring the 'strUrl' inside or outside the loop doesn't have any
impact on how and when the objects pointed to are collected (it's the
same as the same IL is produced). So, is the object collected when you
assign another value to 'strUrl'? Nope. (Assuming the collector doesn't
kick in at that moment, and normally it won't). So only the reference
to the previous object is lost. BTW, it won't get collected as
'arrLongListOfURLs' still has a reference to it.
You shouldn't even bother that much about creating lots of small
objects, but of course, using less objects will always use less space
and time. The fastest application does not create any object, but it
won't do anything useful either ;) If you can do the same thing with
half the amount of objects, you should go that way.
Closing or disposing the webrequest (don't really know the class) before
assigning a new instance to the variable is a good practice.

regards,
Benoit
 
The memory issue is small as strings are reference types. The second is
probably better are it will re-use the same memory instead of asking for new
memoruy everytime.

Ciaran
 
I think you'll find that a string is a reference type and there the object
will be on the heap and a reference will be on the stack. Only objects
derived from System.ValueType actually live on the stack.

Ciaran
 
Ciaran said:
The memory issue is small as strings are reference types. The second is
probably better are it will re-use the same memory instead of asking for new
memoruy everytime.

What would be "asking for new memory" every time? The two pieces of
code are identical as far as the IL is concerned, but the first is
cleaner in terms of limiting the scope of a variable to its use.
 
Ciaran said:
I think you'll find that a string is a reference type and there the object
will be on the heap and a reference will be on the stack. Only objects
derived from System.ValueType actually live on the stack.

No - the values of all local variables live on the stack. For reference
types, that means the references themselves rather than the objects,
but they still take up stack space.
 
Back
Top