September 08, 2007
Nathan Reed wrote:
> mandel wrote:
>> It's nice not to have to sacrifice speed for reliability.
> 
> In a garbage collected language like D, allocations are extremely fast, potentially several times faster than heap based languages like C/C++.
> 
> Using a new instance of the object for each iteration of the loop is really what you're doing /conceptually/, anyway...so, I wouldn't worry about the allocation performance too much unless you've profiled the app and established that it is a bottleneck.

Or if there's some reason that the object must be re-initialized in place--say, to preserve its address.  One could argue that this necessity indicates a poor program design, but I imagine there are cases where it may apply.

For what it's worth, this would be quite easy to accomplish if D supported placement new as a default construction method (rather than requiring the user to override operator new to do so).  Then, re-initializing an object would be as simple as:

this = new(this) typeof(this);

(assuming the runtime doesn't do anything too weird in _d_new)

> And if that's the case you might want to think about making the object a struct (so a value-type, allocated on the stack) anyway.

Good point.


Sean
September 09, 2007

Sean Kelly wrote:
> [snip]
>
> Or if there's some reason that the object must be re-initialized in place--say, to preserve its address.  One could argue that this necessity indicates a poor program design, but I imagine there are cases where it may apply.

Or you might just be dealing with thousands of frequently created and destroyed tiny, tiny objects and yes the overhead of allocating/deallocating *is* an issue.

Like pretty sparkly particles -- free lists are your friend! :)

> For what it's worth, this would be quite easy to accomplish if D supported placement new as a default construction method (rather than requiring the user to override operator new to do so).  Then, re-initializing an object would be as simple as:
> 
> this = new(this) typeof(this);
> 
> (assuming the runtime doesn't do anything too weird in _d_new)

That makes me uneasy because then you can't overload new(void*) for
anything.  Maybe...

void* inplace(TypeInfo ti, size_t size, void* custom_arg)
{
    return custom_arg;
}

this = new.inplace(this) typeof(this);

So make a special case of the unified function call syntax such that if you have a function whose first two arguments are (TypeInfo,size_t), then it can be called as a "member" of new.  This allows classes to override new as necessary, whilst still providing a way to do more general overloads.

>> And if that's the case you might want to think about making the object a struct (so a value-type, allocated on the stack) anyway.

Sorry, pretty sparkly particles must persist across stack frames :(

	-- Daniel
September 09, 2007
Daniel Keep wrote:
> 
>>> And if that's the case you might want to think about making the object
>>> a struct (so a value-type, allocated on the stack) anyway.
> 
> Sorry, pretty sparkly particles must persist across stack frames :(

It's possible to use 'new' for structs too :-p


Sean
September 09, 2007
Sean Kelly wrote:

> Nathan Reed wrote:
>> Using a new instance of the object for each iteration of the loop is really what you're doing /conceptually/, anyway...so, I wouldn't worry about the allocation performance too much unless you've profiled the app and established that it is a bottleneck.
> 
> Or if there's some reason that the object must be re-initialized in place--say, to preserve its address.  One could argue that this necessity indicates a poor program design, but I imagine there are cases where it may apply.

Just to support Seans argument here...

One example from driver development: Some on-card descriptor,
you get mapped via IO memory. The class would be your driver instance for
this card and your descriptor a struct or array member in that class.
You have to re-initialize that descriptor or at least part of after
receive. One usually does that in some cleanup run for many at once.

Network Interface Cards (NICs) often work that way.


Best Regards

Ingo Oeser
September 10, 2007
mandel wrote:
> Hi,
> 
> I have some big classes with lots of member variables
> that need to be reset to theire initial value.
> Therefore I thought about a more reliable way to
> accomplish this, because it's hard to keep track
> of variables I have added.
> It also looks bloated to assign all values manually.
> 
> class Foo
> {
> 	uint x;
> 	char[] name = "world";
> //problematic:
> 	const uint y;
> 	char[1024] buffer;
> 	
> 	void reset()
> 	{
> 		scope tmp = new typeof(this);
> 		foreach(i, x;  tmp.tupleof)
> 		{
> 			this.tupleof[i] = x;
> 		}
> 	}
> }
> 
> The problem is that I have to avoid
> to try to set const values and static arrays.
> 
> How can this be done?

How about putting the member variables you want to reset inside a struct inside the class, eg.

import std.stdio;

class Foo
{
	struct FooData
	{
		int a = 6;
	}
	
	FooData data;
	
	int a() { return data.a; }
	
	void reset() { data = FooData.init; }
}

void main()
{
	auto f = new Foo();
	writefln(f.a);
	f.data.a = 5;
	writefln(f.a);
	f.reset();
	writefln(f.a);
}

The proposed "alias data this" could later be used to bring the members of FooData into the scope of Foo allowing you to access them as "f.a" without property methods.

Regan
1 2
Next ›   Last »