August 31, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:aknd4g$2kgn$1@digitaldaemon.com... > A slice is just a pointer and size register pair, right? Yes. > So just mention in > the spec that if you resize a dynamic array, all slices of it become > invalid. That's the best idea yet. It might actually work <g>. The downside, of course, is it can lead to subtle and disastrous programming bugs. > Or maybe resizing a dynamic array that has had slices made of it, requires it to be copied (leaving the old array untouched, until GC reclaims it) That turns every slice into a function call with some arbitrary code being executed. |
August 31, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:akpd4j$231a$1@digitaldaemon.com... > > "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:aknd4g$2kgn$1@digitaldaemon.com... > > A slice is just a pointer and size register pair, right? > > Yes. > > > So just mention in > > the spec that if you resize a dynamic array, all slices of it become > > invalid. > > That's the best idea yet. It might actually work <g>. The downside, of course, is it can lead to subtle and disastrous programming bugs. Right. It would be a good source of bugs. Just like iterators in STL. ;) > > Or maybe resizing a dynamic array that has had slices made of it, requires > > it to be copied (leaving the old array untouched, until GC reclaims it) > > That turns every slice into a function call with some arbitrary code being executed. No, that means every time you slice an array you have to set a flag bit somewhere in the array so that when the array is resized, it will know it must be copied somewhere else safe, leaving the existing slices unharmed, and of course clear the bit in the new copy. 99% of the work happens during darray resize, which is going to be slow anyway. Maybe it's a bad idea... that setting of a bit per slice operation may add up to be noticeable. Sean |
August 31, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:akptsn$2l4q$1@digitaldaemon.com... > No, that means every time you slice an array you have to set a flag bit somewhere in the array so that when the array is resized, it will know it must be copied somewhere else safe, leaving the existing slices unharmed, and of course clear the bit in the new copy. 99% of the work happens during > darray resize, which is going to be slow anyway. > > Maybe it's a bad idea... that setting of a bit per slice operation may add up to be noticeable. This would require not only setting a bit per slice, but setting that bit every time you make a copy of a reference to an array. Issues similar to reference counting come up. |
September 01, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Currently, how do you resize slices? Just another idea to add to the list. Parhaps an array could be taged as either having extra elements or not using a single bit. Arrays that do not have this bit set would be treated normally, until they are resized. When an array is resized the bit is set and it is oversized my a predefinded step. When the gc runs it could also perform an action to reclaim memory, by simply removing the bit. ie For example (jumps of 10) Length = 8 size = 8 items (with out bit set) Length = 8 size = 10 items (with bit set) Length = 12 size = 12 items (with out bit set) Length = 12 size = 20 items (with bit set) This way there would be only one extra bit needed per array. If you have memory to spare a frame count could be added to the array (ie a byte), so that array items could have slighly longer life times. Still theres problems with slices. I think slices should be dealt with like this at compile time as a constant array. const int[] Slice; const int[] Slice2; int [] something; ... //Assign slice Slice = Something[1..10]; //As a parmitor function(const int[] aSlice) { } //Implicit conversion Something = Slice; //Implicit conversion Slice = Something; //Error Slice = Slice ~ Somthing; //Impicit conversion Something = Slice ~ Something; //Fine Slice = Slice2; "Walter" <walter@digitalmars.com> wrote in message news:akr27q$143p$1@digitaldaemon.com... > > "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:akptsn$2l4q$1@digitaldaemon.com... > > No, that means every time you slice an array you have to set a flag bit somewhere in the array so that when the array is resized, it will know it > > must be copied somewhere else safe, leaving the existing slices unharmed, > > and of course clear the bit in the new copy. 99% of the work happens > during > > darray resize, which is going to be slow anyway. > > > > Maybe it's a bad idea... that setting of a bit per slice operation may add > > up to be noticeable. > > This would require not only setting a bit per slice, but setting that bit every time you make a copy of a reference to an array. Issues similar to reference counting come up. > > |
September 01, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "anderson" <anderson@firestar.com.au> wrote in message news:aktj5r$t5d$1@digitaldaemon.com... > Currently, how do you resize slices? allocate a new size and copy. > Just another idea to add to the list. > Parhaps an array could be taged as either having extra elements or not using > a single bit. Arrays that do not have this bit set would be treated normally, until they are resized. When an array is resized the bit is set and it is oversized my a predefinded step. When the gc runs it could also perform an action to reclaim memory, by simply removing the bit. > > ie > For example (jumps of 10) > Length = 8 size = 8 items (with out bit set) > Length = 8 size = 10 items (with bit set) > Length = 12 size = 12 items (with out bit set) > Length = 12 size = 20 items (with bit set) > > This way there would be only one extra bit needed per array. > > If you have memory to spare a frame count could be added to the array (ie a > byte), so that array items could have slighly longer life times. > > Still theres problems with slices. > > I think slices should be dealt with like this at compile time as a constant > array. > > const int[] Slice; > const int[] Slice2; > int [] something; > ... > > //Assign slice > Slice = Something[1..10]; > > //As a parmitor > function(const int[] aSlice) > { > > } > > //Implicit conversion > Something = Slice; > > //Implicit conversion > Slice = Something; > > //Error > Slice = Slice ~ Somthing; > > //Impicit conversion > Something = Slice ~ Something; > > //Fine > Slice = Slice2; Setting a bit means that accessing an array means masking off the bit. There can be a significant penalty for loops doing this. |
September 02, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:aku2uu$1e8m$1@digitaldaemon.com... > > "anderson" <anderson@firestar.com.au> wrote in message news:aktj5r$t5d$1@digitaldaemon.com... > > Currently, how do you resize slices? > > allocate a new size and copy. > > > Just another idea to add to the list. > > Parhaps an array could be taged as either having extra elements or not > using > > a single bit. Arrays that do not have this bit set would be treated normally, until they are resized. When an array is resized the bit is set > > and it is oversized my a predefinded step. When the gc runs it could also > > perform an action to reclaim memory, by simply removing the bit. > > > > ie > > For example (jumps of 10) > > Length = 8 size = 8 items (with out bit set) > > Length = 8 size = 10 items (with bit set) > > Length = 12 size = 12 items (with out bit set) > > Length = 12 size = 20 items (with bit set) > > > > This way there would be only one extra bit needed per array. > > > > If you have memory to spare a frame count could be added to the array (ie > a > > byte), so that array items could have slighly longer life times. > > > > Still theres problems with slices. > > > > I think slices should be dealt with like this at compile time as a > constant > > array. > > > > const int[] Slice; > > const int[] Slice2; > > int [] something; > > ... > > > > //Assign slice > > Slice = Something[1..10]; > > > > //As a parmitor > > function(const int[] aSlice) > > { > > > > } > > > > //Implicit conversion > > Something = Slice; > > > > //Implicit conversion > > Slice = Something; > > > > //Error > > Slice = Slice ~ Somthing; > > > > //Impicit conversion > > Something = Slice ~ Something; > > > > //Fine > > Slice = Slice2; > > Setting a bit means that accessing an array means masking off the bit. There > can be a significant penalty for loops doing this. > Howable using an entire byte for a lifetime value instead. |
September 02, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
Walter a écrit :
>
> for (i = 0; i < a.length; i++)
>
> becomes:
>
> for (i = 0; i < (a.length & 7FFFFFFF); i++)
>
> which can have a significant speed penalty.
it seems to me not much if end_index (a.length & 7FFFFFFF) is evaluated only
once.
if end_index need to be evaluated at each iteration of the loop, the loop can
be rewritten like this:
for (i=0 | (a.lenght & (0x1000000)); i < a.length; i++)
roland
|
September 02, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "anderson" <anderson@firestar.com.au> wrote in message news:akvere$2li$1@digitaldaemon.com... > Howable using an entire byte for a lifetime value instead. Right now, a reference to a dynamic array is a 2 word quantity. It fits nicely into the code generator which deals efficently with register pairs. Increasing the size of the reference will make for much less efficient code to handle the references. |
September 02, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roland | "Roland" <rv@ronetech.com> wrote in message news:3D73B504.4DE3E1C9@ronetech.com... > Walter a écrit : > > for (i = 0; i < a.length; i++) > > becomes: > > for (i = 0; i < (a.length & 7FFFFFFF); i++) > > which can have a significant speed penalty. > it seems to me not much if end_index (a.length & 7FFFFFFF) is evaluated only > once. > if end_index need to be evaluated at each iteration of the loop, the loop can > be rewritten like this: > > for (i=0 | (a.lenght & (0x1000000)); i < a.length; i++) True, but proving that the length of the array does not change within the loop, directly or indirectly, is non-trivial. |
September 11, 2002 Re: Some more ideas | ||||
---|---|---|---|---|
| ||||
Posted in reply to Juan Carlos Arevalo Baeza | "Juan Carlos Arevalo Baeza" <jcab@JCABs-Rumblings.com> wrote in message news:akm8rv$1e9n$1@digitaldaemon.com... > "Walter" <walter@digitalmars.com> wrote in message news:aklmo8$pm3$1@digitaldaemon.com... > > > > You can always store the size _and_ capacity as part of the allocated > > > block of memory. It would mean an extra level of indirection for some operations, but the dynamic array would occupy one register, instead of > > two. > > > It's somewhat of a tradeoff, but it sounds reasonable to me: extra > > > indirection (optimizable in many cases), smaller register footprint and > > > better reallocation in the worst case. > > > > That would require a memory allocation (for the 3 word quantity) for every > > dynamic array. I suspect it would be a big hit on performance. > > No. Just allocate it together (in the same block of memory as) the array > elements themselves. No performance hit besides the extra indirection and any calculations neccessary to preserve alignment. > > It's a pretty common thing to do. All implementations of std::string that > I know (except one - flex_string by Alexandrescu, which allocates it separately) of use this to store the string's reference counter, for example. Thats how Delphi does it, a dynamic array is a pointer, the first 2 words of the memory block are the ref count and the number of elements . The pointer points to the first element of the array so the ref cound is at -8 and lenght is at -4. Also in delhpi strings are arrays with copy on write but the neat thing Delphi does is that it automaticly maintans a trailing null char at the end. So to cast a delphi string to a C string you just point at the first char, zero overhead. And because the lenght is stored you dont have to scan the string to determine its length. chris |
Copyright © 1999-2021 by the D Language Foundation