Fixing const arrays

Steven Schveighoffer schveiguy at yahoo.com
Wed Dec 14 12:59:10 PST 2011


On Wed, 14 Dec 2011 15:39:55 -0500, Peter Alexander  
<peter.alexander.au at gmail.com> wrote:

> On 14/12/11 8:16 AM, Timon Gehr wrote:
>> On 12/14/2011 12:35 AM, Peter Alexander wrote:
>>> On 13/12/11 11:11 PM, Timon Gehr wrote:
>>>> On 12/14/2011 12:14 AM, Peter Alexander wrote:
>>>>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>>>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu
>>>>>> wrote:
>>>>>>> There's a phrase in Romanian that quite applies: "From the lake  
>>>>>>> into
>>>>>>> the well".
>>>>>>
>>>>>> I believe the English version is "Out of the frying pan, into the
>>>>>> fire" :)
>>>>>>
>>>>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>>>>> because it's a common feature among PLs, it's better than nothing,  
>>>>>> and
>>>>>> don't know better solutions.
>>>>>
>>>>> In my opinion, it's not better than nothing.
>>>>>
>>>>> What it gives you:
>>>>>
>>>>> 1. A bit of syntactic sugar.
>>>>> 2. The ability to refactor member look up easily.
>>>>>
>>>>> What it costs:
>>>>>
>>>>> 1. Overloads syntax.
>>>>> a. obj.field can now be an arbitrary function call.
>>>>> b. May have arbitrary cost (e.g. T[].length)
>>>>
>>>> ??? T[].length is a field access, not a property function. It takes a
>>>> small constant amount of time.
>>>
>>> Assigning to the length of an array may reallocate it, which is not a
>>> small, nor constant amount of time.
>>>
>>> int[] a;
>>> ...
>>> a.length = n; // may invoke a GC allocation + O(n) memcpy
>>
>> OK, I see, thanks. I don't think it is problematic in this particular
>> case though.
>
> Well, it is a little. It makes it difficult to scan code looking for GC  
> allocations, or even scan code looking for inefficiencies.
>
> Obviously I know now that I have to look for .length assignments on  
> arrays, but it can be quite horrific when looking at code that uses  
> third party libraries that you aren't familiar with.
>
> An example of this I encountered in practice was in Unity3D's libraries.
>
> http://unity3d.com/support/documentation/ScriptReference/WWW-texture.html
>
> The WWW class has a 'texture' property. A small sentence in the middle  
> of its documentation reveals the horror.
>
> "Each invocation of texture property allocates a new Texture2D."
>
> That's right. Every time you read WWW.texture, it allocates a large  
> chunk of memory. In my particular case, I was copying the pixels from  
> the texture into another array, something like this:
>
> WWW www = ...;
>
> for (int i = 0; i < www.texture.width; ++i)
>      for (int j = 0; j < www.texture.height; ++j)
>          buffer[i][j] = www.texture.GetPixel(i, j);
>
> For a small 100x100 texture, that code allocates over 10,000, 100x100  
> textures.
>
> Luckily, that was horrific enough to prompt me to investigate, but a  
> less obvious problem would have likely slipped past me unnoticed.

Yes, but length as a read property does not allocate anything (nor does  
reducing the length).  In fact, length as a read property reduces to a  
field access (it is a language builtin, after all).

Would you expect that setting the length of an array to a *larger* size  
would not allocate?  Your example shows something that doesn't look like  
it should be costly, but it actually is.  Expanding length *looks* costly  
(and it is).

You do have a point that it shouldn't necessarily be a property.  I also  
don't think dup, reverse, or sort should be array properties.  But these  
are pieces of the language that have been there forever.  To change them  
now would be disruptive for very little gain.

-Steve


More information about the Digitalmars-d mailing list