April 26, 2009
Andrei Alexandrescu:
> 1. As right now :o).
> 2. Using refcounting. [...]
> 3. Using manual management. [...]
> If we manage to integrate them all... that's quite the holy grail. And I
> think it's entirely possible with only a few changes to the language.

If you add such two other ways to manage memory, you end with different code. Isn't this going to split the D codebase in three? (If I look for an already written D1 module now I have to see if it's for Tango or Phobos. In such situation I have to see what kind of memory does it use?)

And in big programs isn't the usage of a GC inevitable? So are the other two options only for small programs?

When you see code written by other people you must be able to understand and know how to use the refcounting too. So this adds some more things to know. D2 is getting more and more complex than D1. Eventually D2 may risk getting too much complex for normal people. Both C and Java are simple enough languages, but a cross of them may be too much complex for normal people.

Bye,
bearophile
April 26, 2009
On 2009-04-25 19:44:18 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> There are three schemes that are good starting points:
> 
> 1. As right now :o).
> 
> 2. Using refcounting. Arrays will be 4 words long (begin, end, end-of-store, refcount*) and slices will be 3 words long (begin, end, and owner*)
> 
> 3. Using manual management. Arrays will be 3 words long (begin, end, end-of-store) and slices will be 2 words long (begin, end). This is close to C++/STL. This case is less safe but very efficient.
> 
> If we manage to integrate them all... that's quite the holy grail. And I think it's entirely possible with only a few changes to the language.

1 and 2 certainly look useful.

I've never found 3 to be efficient in the C++/STL. Making a copy every time you need to store a string in a struct isn't something I call efficient. Especially in a language that supports immutable strings, reference counting seems immencely preferable. And reference counting has the advantage that it does not require any change or addition to the language syntax or semantics.

Andrei, do you have a use case for 3 that would end up worse using reference counting? Because I only see appending, and even then, appending when the refcount is 1 could be done in-place which would be pretty efficient.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

April 26, 2009
On Sun, 26 Apr 2009 03:21:08 -0400, Rainer Deyke <rainerd@eldwood.com> wrote:
> Robert Jacques wrote:
>> 1) Immutable strings are often concatenated, which you don't address
>
> There are two types of concatenation: in-place (operator ~=) and not
> (operator ~).  The former can take advantage of capacity to avoid new
> allocation, the latter can not.

Actually, both ~= and ~ use capacity to avoid new allocation.

> When concatenating a lot of immutable strings, it might make sense to
> make the left side mutable:
>
> char[] tmp = string1.dup;
> tmp ~= string2;
> tmp ~= string3;
> // ...
> tmp ~= string99;
> string result = tmp.idup;

Why make 2 extra copies if you don't need too?

>> 2) int[], real[], and basically anything not a string rarely
>> concatenates, but often mutable, which you don't address
>
> I frequently append individual elements to non-string arrays.

Cool. Care to elaborate on your use case?
I was thinking of scientific computing (linear algebra, optimization) and game programming.

Since we're off the topic of T[new] and onto a capacity field in general, I'd like to point out the older newsgroup posts:
http://www.digitalmars.com/d/archives/digitalmars/D/Array_Capacity_Field_71119.html
http://www.digitalmars.com/d/archives/digitalmars/D/Array_append_performance_75410.html
http://www.digitalmars.com/d/archives/digitalmars/D/Array_append_performance_2_75811.html
April 26, 2009
Andrei Alexandrescu wrote:
> Christopher Wright wrote:
>> Simple solution: put the array definition in object.d and try implementing arrays with reference counting or manual memory management.
>>
>> I think stored slices break manual memory management, even with a dedicated slice type; but they should work just fine with refcounting. If you don't want to change the language, object.Array will have to implement the logic for slices and for allocated arrays. It's a bit ugly, and it makes the Array type larger. Also, Array's reference count would need to be accessed by reference.
> 
> There are three schemes that are good starting points:
> 
> 1. As right now :o).
> 
> 2. Using refcounting. Arrays will be 4 words long (begin, end, end-of-store, refcount*) and slices will be 3 words long (begin, end, and owner*)

Well, a slice will be begin, end, owner-ref-count*. The owner could move about the stack or get passed between classes on the heap or something like that.

> 3. Using manual management. Arrays will be 3 words long (begin, end, end-of-store) and slices will be 2 words long (begin, end). This is close to C++/STL. This case is less safe but very efficient.
> 
> If we manage to integrate them all... that's quite the holy grail. And I think it's entirely possible with only a few changes to the language.

Agreed.
April 26, 2009
Just my 2 cents.  I use a C++ array template that optimizes memory usage by only storing a pointer.  It stores the capacity and the size in the heap allocation.  The benefit here is that empty arrays only require one word.  I am the primary author of a simulation engine (similar to a game engine but less graphics-focused).  In practice I have found about half of all arrays are empty, so this approach provides much better memory efficiency for my purposes.

-Craig 

April 27, 2009
On Sat, 25 Apr 2009 12:56:15 -0400, Unknown W. Brackets <unknown@simplemachines.org> wrote:

> Well, a range of an associative array is a possibility (not a slice, but e.g. from std.algorithm.)
>
> I think it'd be a mistake to discount that.  Being able to treat associative arrays like arrays, in some cases (e.g. with count(), etc.) is nice.  That said, i don't even know that std.algorithm currently supports this.

Sure, but why should a range type of an AA be a special builtin type?  It makes sense with array slices because they are valuable to use in many different ways, can be useful as sub-ranges, and keep their value long after the array has been changed.  An AA range would be useful only for iterating over all the elements.  Once the AA changes, the AA range is invalid.  Making a subrange is pretty much useless, since there's no real order to the data.  When a range is necessarily the range of the entire container, it becomes a trivial addition to the typesystem just to meet interface requirements.  Array slices are way more useful than that.

I'd say A[U] is the container type, and AARange!(A, U) is the range if you wish to have a type name.  I see no reason to add a builtin type to deal with AA ranges.

-Steve
1 2 3 4 5
Next ›   Last »