June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:aek6k2$1d57$1@digitaldaemon.com... > Isn't that gonna make a lot of other writeable properties hard to use? The > syntax is shared for all properties (including user-defined ones, if I'm right) so it seems to make sense to make it flexible for use by user properties which should work just like normal variables correct? I think the .length property is going to wind up being a special case. (I hate special cases.) |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | anderson wrote:
> That reminds me of what we used to do in C to speed up malloc/realloc. Block
> allocation is the key.
>
> Parhaps .length++ could increase by n (ie 10) values or n% (ie 2%) and then
> it'd only need to update when it gets passed that number again.
Python uses a specific function for overallocation that they claim gives linear reallocation speed on poorly performing reallocs, such as, uh, Windows'. I stuffed that in my realloc wrapper function so now I just reallocate everything up by one, secure in the knowledge that it'll be fast. The function is:
static int
__roundupsize (int n)
{
unsigned int nbits = 0;
unsigned int n2 = (unsigned int) n >> 5;
do
{
n2 >>= 3;
nbits += 3;
}
while (n2);
return ((n >> nbits) + 1) << nbits;
}
Python's source goes into its behaviour and results and I can dig that up if it's wanted.
Arrays could be given a third integer for maximum that's set to length in slices and static arrays but is overallocated otherwise. Once it tops it, allocate the new array and copy it over. Resizing to lower lengths causes maximum to equal length, as it's essentially a slice operator.
One real problem that comes up is in multiple array references:
a = foo; /* foo is a dynamic array */
b = foo;
a ~= 4;
b ~= 8;
a [a.length - 1] == 8 or == 4 depending upon whether (maximum != length) before the append.
One solution would be that when making a reference copy of an array the maximum field is set to length, so that a and b always get their own copy when appending.
I can't think of any other problems, but Walter would certainly know what could go wrong.
|
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "anderson" <anderson@firestar.com.au> wrote in message news:aeks0b$24p8$1@digitaldaemon.com... > I don't agree. Any decent programmer with half a brain would beable to notice that one. I see that kind of code all the time, over and over. I saw it again recently in a popular benchmark program. I've shown many people how they can improve performance a thousand+ fold by preallocating the array. I believe that by supporting ++ on the .length, that would implicitly bless that wrong technique. > Besides, what's going to stop them from doing ... > > for (i = 0; i < n; i++) > { > array.length = array.length + 1; > array[n] = foo(); > } > > or > > for (i = 0; i < n; i++) > { > array.length = n + 1; > array[n] = foo(); > } Absolutely nothing will prevent them from writing the loop that way. |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Agree. If they want to do it badly, let them do it longhand "Walter" <walter@digitalmars.com> wrote in message news:aelvi3$onf$1@digitaldaemon.com... > > "anderson" <anderson@firestar.com.au> wrote in message news:aeks0b$24p8$1@digitaldaemon.com... > > I don't agree. Any decent programmer with half a brain would beable to notice that one. > > I see that kind of code all the time, over and over. I saw it again recently > in a popular benchmark program. I've shown many people how they can improve > performance a thousand+ fold by preallocating the array. > > I believe that by supporting ++ on the .length, that would implicitly bless > that wrong technique. > > > > Besides, what's going to stop them from doing ... > > > > for (i = 0; i < n; i++) > > { > > array.length = array.length + 1; > > array[n] = foo(); > > } > > > > or > > > > for (i = 0; i < n; i++) > > { > > array.length = n + 1; > > array[n] = foo(); > > } > > Absolutely nothing will prevent them from writing the loop that way. > > |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:ael7ve$163$1@digitaldaemon.com... > I just don't see the potential misuse of a otherwise useful feature as > grounds for not including it in the language. > Most people wouldn't care. They'd write it, it'd be slow, and they'd not > care or in fact even notice. The performance penalty of such a loop can easilly reduce a 2GHz machine to behave worse than a 4.77MHz PC! I've seen it. The problem is it isn't incrementally worse, it's exponentially worse, and a powerful exponential at that. > Only us speed freaks care, and we would never write slop such as that because part of caring about performance is understanding what the compiler > is transforming your code into. Unfortunately, people do routinely write such code. |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "anderson" <anderson@firestar.com.au> wrote in message news:ael937$2qm$1@digitaldaemon.com... > That reminds me of what we used to do in C to speed up malloc/realloc. Block > allocation is the key. > Parhaps .length++ could increase by n (ie 10) values or n% (ie 2%) and then > it'd only need to update when it gets passed that number again. Even C++'s vector did that. That was the original plan, but due to the way array slicing works, there's no way for the GC to tell that there's "unused" space off the end of the array. Hence, it must reallocate and copy every time. The result is terrible performance - the cure is to preallocate the length you'll need, or use OutBuffer which will do block reallocation in suitable increments. |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Thanks, I didn't think you'd miss that. "Walter" <walter@digitalmars.com> wrote in message news:aem052$p8b$2@digitaldaemon.com... > > That was the original plan, but due to the way array slicing works, there's > no way for the GC to tell that there's "unused" space off the end of the array. Hence, it must reallocate and copy every time. The result is terrible > performance - the cure is to preallocate the length you'll need, or use OutBuffer which will do block reallocation in suitable increments. > > |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | Check out OutBuffer in the Phobos library, it is tuned for incrementally building an array. "Burton Radons" <loth@users.sourceforge.net> wrote in message news:3D0E80EC.9090708@users.sourceforge.net... > anderson wrote: > > That reminds me of what we used to do in C to speed up malloc/realloc. Block > > allocation is the key. > > > > Parhaps .length++ could increase by n (ie 10) values or n% (ie 2%) and then > > it'd only need to update when it gets passed that number again. > > Python uses a specific function for overallocation that they claim gives linear reallocation speed on poorly performing reallocs, such as, uh, Windows'. I stuffed that in my realloc wrapper function so now I just reallocate everything up by one, secure in the knowledge that it'll be fast. The function is: > > static int > __roundupsize (int n) > { > unsigned int nbits = 0; > unsigned int n2 = (unsigned int) n >> 5; > > do > { > n2 >>= 3; > nbits += 3; > } > while (n2); > > return ((n >> nbits) + 1) << nbits; > } > > Python's source goes into its behaviour and results and I can dig that up if it's wanted. > > Arrays could be given a third integer for maximum that's set to length in slices and static arrays but is overallocated otherwise. Once it tops it, allocate the new array and copy it over. Resizing to lower lengths causes maximum to equal length, as it's essentially a slice operator. > > One real problem that comes up is in multiple array references: > > a = foo; /* foo is a dynamic array */ > b = foo; > > a ~= 4; > b ~= 8; > > a [a.length - 1] == 8 or == 4 depending upon whether (maximum != > length) before the append. > > One solution would be that when making a reference copy of an array the maximum field is set to length, so that a and b always get their own copy when appending. > > I can't think of any other problems, but Walter would certainly know what could go wrong. > |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Just a question/thought ... for (i = 0; i < n; i++) if (...) A1[A1.length++] = foo(); converted to the complier language equilent to into ... for (i = 0; i < n; i++) { if (...) if (A1.length == ++CurrentLength ) A1.length = A1.length + 10; //Or A1.length = A1.length + A1.length >> 1 A1[] = foo(); } } TrimArray(A1); ...when ever it finds a .length++ inside that loop. The nesting levels and amount the complier has to traverse would be a problem. Although it wouldn't have to traverse function with "in arrays" because the length shouldn't beable to be changed on these. Of coarse that would still run slower then doing it outside the loop. In somecases it's impossible to predict if the array will be resized inside the loop or not, and so code like that needs to be written anyway. But as you said, there's an "OutBuffer" that simplifies that? Although I know theres probably a perfectly good reason not to use this. |
June 18, 2002 Re: resizing arrays won't work | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | Didn't anyone noticed that the following example is not valid not only for current DMD (as long as Walter doesn't allow ++ on properties) but is simply *buggy*? > int array[]; > array[array.length++] = x; AFAIK, the sequence of event will be: array[array.length] = x; array.length=array.length+1; And it is simply not valid array expanding. It's a bug which in the best case will give GPF (in the worst it silently corrupts memory). In fact, the sequence should be: array.length=array.length+1; array[array.length-1] = x; which corresponds to array[(++array.length)-1] = x; And after all, I really think that form is not very good. I agree that properties should have only gettors and settors, and ++, --, etc, should not be used with them. Nic Tiger. "anderson" <anderson@firestar.com.au> wrote in message news:aee8qd$1adv$1@digitaldaemon.com... > Then the following lines in the "Programming in D for C Programmers" must be > wrong. I suppose Walter hasn't go around to updating it (Apr 21) and parhaps > still plans to use this syntax later on. > > " > The D Way > D supports dynamic arrays, which can be easilly resized. D supports all the > requisite memory management. > int array[]; > > array[array.length++] = x; > > " |
Copyright © 1999-2021 by the D Language Foundation