View mode: basic / threaded / horizontal-split · Log in · Help
December 03, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On 12/1/2012 3:43 PM, Jonathan M Davis wrote:
> Any struct which contains reference types needs them. For instance, a struct
> containing int[] needs to dup that array if it doesn't want to have the copy
> referring to the same elements as the original and therefore risk having them
> be mutated. Arrays with immutable elements don't have that problem, but those
> with mutable elements (and to some extent those with const) do have such a
> problem, as to structs with classes or structs which are reference types, etc.
> I'm surprised that you'd think that postblit constructors were only useful for
> implementing reference counting types. IMHO, the language would be crippled
> without a postblit or copy constructor for structs.

On the other hand, I'd say you have a pretty expensive design if it 
required you to allocate memory in order to do a copy. Making copies 
ought to be a cheap operation.

It's not hard to implement copy-on-write for the referenced data. In 
fact, with reference counting, you shouldn't need to make those dups.
December 05, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
Hum...

Hust wanted to add that "Appender" also suffers from this issue. 
It will, on _each_and_every_ append, check if its payload has 
been initialized :/

That's far from ideal behavior for a function that's supposed to 
squeeze as much performance as possible out of array 
manipulation...
December 05, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
Hum...

Just wanted to add that "Appender" also suffers from this issue. 
It will, on _each_and_every_ append, check if its payload has 
been initialized :/

That's far from ideal behavior for a function that's supposed to 
squeeze as much performance as possible out of array 
manipulation...
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On Monday, 3 December 2012 at 22:34:08 UTC, Walter Bright wrote:
> Making copies ought to be a cheap operation.


Beg to differ here.

Copying pointers ought to be cheap. Copying objects ought to be 
expensive.
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On 12/8/2012 5:00 PM, Mehrdad wrote:
> Copying objects ought to be expensive.

I don't understand the rationale for that.
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On Sunday, December 09, 2012 10:58:45 Walter Bright wrote:
> On 12/8/2012 5:00 PM, Mehrdad wrote:
> > Copying objects ought to be expensive.
> 
> I don't understand the rationale for that.

I can see an argument that there's no requirement that copying objects be 
cheap, since there are plenty of objects where it's _not_ cheap to copy them 
and where it can't be cheap to copy them, but I don't see any argument for 
them _supposed_ to be being expensive to copy. I suspect that Merhdad just 
phrased it incorrectly.

D and Phobos seem to be trying to take the tact that copying objects is 
supposed to be cheap and expect it to be cheap. But I honestly don't see how 
anyone can expect that to be relied upon. There are things that can be done to 
reduce the cost of copying an object (like COW), but l think that if you 
honestly expect that people aren't going to do stuff like

this(this)
{
   a = a.dup;
}

then you're deluding yourself. That's kind of the point of having posblits in 
the first place, and it's basically the example that TDPL gives as to what 
postblits do. And depending on the type of a's elements, that copy could be 
far worse than O(1). And even if it weren't, there's nothing stopping the 
programmer from doing other expensive operations in a postblit constructor 
(e.g. doing a deep copy of a red-black tree by recursively copying the whole 
thing).

I'm fine with saying that various algorithms will be far more expensive if your 
struct defines an expensive postblit and that defining an expensive postblit is 
best avoided if possible, but there _will_ be plenty of expensive postblits in 
real world code. The only way that you can guarantee that copying structs is 
cheap is if you make it impossible to do a deep copy (i.e. get rid of 
postblit), which would be _far_ too limiting. Even stuff like ref-counted 
structs would become impossible in that case, because it's postblit which 
makes them possible as well.

- Jonathan M Davis
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On Sunday, 9 December 2012 at 19:17:06 UTC, Jonathan M Davis 
wrote:
> On Sunday, December 09, 2012 10:58:45 Walter Bright wrote:
>> On 12/8/2012 5:00 PM, Mehrdad wrote:
>> > Copying objects ought to be expensive.
>> 
>> I don't understand the rationale for that.
>
> I can see an argument that there's no requirement that copying 
> objects be cheap, since there are plenty of objects where it's 
> _not_ cheap to copy them and where it can't be cheap to copy 
> them, but I don't see any argument for them _supposed_ to be 
> being expensive to copy. I suspect that Merhdad just phrased it 
> incorrectly.


+1 yup, sorry if it was confusing but Jon's clarification i what 
I meant.
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
To elaborate... what's the point of making everything cheap to 
copy?

Copying of an object is _not_ an operation like swap() or "move", 
which are essential to many algorithms.

Indeed, an object might not want to be copyable at all, or it 
might need to perform some expensive operation (as in Jon's 
example) in order for the copy to behave like a copy is supposed 
to.


The only thing that the arbitrary requirement "copies are 
supposed to be cheap" would do is that it would slow down 
everything else, forcing checks on operations that shouldn't need 
to be checked. And it's completely unnecessary unless you're 
working with reference types, in which case copying is already 
cheap anyways.


So basically, algorithms should _expect_ copying of arbitrary 
objects to be expensive, and there's no need for them to be 
otherwise. C++'s swap() illustrates the lack of the need for 
copying beautifully -- often times the only objects I copy 
"generically" in C++ are iterators. I never find the need to copy 
other objects... and I believe D has no such need, either.
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On Sunday, 9 December 2012 at 20:02:15 UTC, Mehrdad wrote:
> I never find the need to copy other objects...


Correction:

I _rarely_ find the need to copy other objects for _generic_ (er, 
templated) types (iterators being the exception I mentioned).

But obviously copying is essential for many concrete classes, 
e.g. vector. And I have never had the need for copying a vector 
to be "cheap" in any sense... in fact, I feel it _should_ be 
expensive, because of what it's doing. So it works out perfectly.
December 09, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
On Sunday, December 09, 2012 21:02:14 Mehrdad wrote:
> So basically, algorithms should _expect_ copying of arbitrary
> objects to be expensive, and there's no need for them to be
> otherwise. C++'s swap() illustrates the lack of the need for
> copying beautifully -- often times the only objects I copy
> "generically" in C++ are iterators. I never find the need to copy
> other objects... and I believe D has no such need, either.

It's been a debate for some time whether Phobos should be able to rely on 
copying being cheap. Algorithms end up copying all the time, and it greatly 
simplifies things if you don't have to worry about copying being expensive. 
Being able to rely on copying being O(1) is something that Andrei has tried to 
push for, but I don't see how we really can given simple things like the need 
to dup arrays - though I can see arguing that it's up to the caller to make 
copying cheap if they want certain algorithms to be more efficient.

The whole reason that the move* primitives were introduced was to try and 
combat expensive copying, but they complicate things a fair bit and rarely get 
used, even if they should be.

D's move semantics also help, but ultimately, some things are just plain going 
to be expensive to copy, and I don't see how you can get around that without 
disallowing certain idioms, which would then cause a different set of problems.

- Jonathan M Davis
1 2 3 4 5 6 7 8 9
Top | Discussion index | About this forum | D home