I have some code where I'm returning an array of objects.
Here's a simplified example:
string[] GetTheStuff() { List<string> s = null; if( somePredicate() ) { s = new List<string>(); // imagine we load some data or something } return (s == null) ? new string[0] : s.ToArray(); }
The question is, how expensive is the new string[0]
?
Should I just return null and make the caller accept null as a valid way of indicating "nothing was found"?
NB: This is being called in a loop which gets run hundreds and hundreds of times, so it's one of the few cases where I think this kind of optimiziation is not actually 'premature'.
PS: And even if it was premature, I'd still like to know how it works :-)
Initially when I asked if it used any space, I was thinking of things from the 'C/C++' point of view, kind of like how in C, writing char a[5];
will allocate 5 bytes of space on the stack, and char b[0];
will allocate 0 bytes.
I realise this is not a good fit for the .NET world, but I was curious if this was something that the compiler or CLR would detect and optimize out, as a non-resizeable array of size zero really shouldn't (as far as I can see?) require any storage space.
It's almost trivial to make an empty array make no space (insofar this is possible). Just represent it as the null pointer. Linked lists have rather different advantages, memory usage is not one of them.
An empty array is an array of length zero; it has no elements: int[] emptyArray = new int[0]; (and can never have elements, because an array's length never changes after it's created).
The size of an empty array is 0, because there are no bytes in it. The size of struct, in general is not zero.
To test if an existing array is an empty array, use isempty . A = ClassName. empty returns an empty 0-by-0 array of the class named by ClassName .
Even if it's being called "hundreds and hundreds" of times, I'd say it's a premature optimization. If the result is clearer as an empty array, use that.
Now for the actual answer: yes, an empty array takes some memory. It has the normal object overhead (8 bytes on x86, I believe) and 4 bytes for the count. I don't know whether there's anything beyond that, but it's not entirely free. (It is incredibly cheap though...)
Fortunately, there's an optimization you can make without compromising the API itself: have a "constant" of an empty array. I've made another small change to make the code clearer, if you'll permit...
private static readonly string[] EmptyStringArray = new string[0]; string[] GetTheStuff() { if( somePredicate() ) { List<string> s = new List<string>(); // imagine we load some data or something return s.ToArray(); } else { return EmptyStringArray; } }
If you find yourself needing this frequently, you could even create a generic class with a static member to return an empty array of the right type. The way .NET generics work makes this trivial:
public static class Arrays<T> { public static readonly Empty = new T[0]; }
(You could wrap it in a property, of course.)
Then just use: Arrays<string>.Empty;
EDIT: I've just remembered Eric Lippert's post on arrays. Are you sure that an array is the most appropriate type to return?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With