mixed lists of objects derived from base class

K

Kraus Christof

Hi,

this problem is similar to the one inquisitive posted earlier today:

to speed up our code I just tried to make use of the 'Curiously
Recursive Template Pattern'... and failed.

The code I'm working on tracks particles (up to a few millions) for a
some tousand time steps. For each time step and each particle a methode
'getExternalField' is called. This method is implemented in different
classes derived from a class 'Component'.

For anyone familiar with particle accelerators, the method returns the
electromagnetic field of elements such as solenoids, rf-cavities aso.
(just differen electromagnetic devices to accelerate and focus
particles). It is (up to now) declared virtual in the base class. Since
it is called so often, it would be nice if we could avoid virtual
functions while still have the flexibily of them.

With the CRT Pattern I would define a solenoid as
class Solenoid: Component<Solenoid>
{
...
};

Now the problem is that I want to have pointers to objects of these
derived classes in an STL list (not only a list of solenoids, but mixed
with other types). For example

Solenoid mySolenoid; //is derived from Component<Solenoid>
RFCavity myRFCavity; //is derived from Component<RFCavity>

list<Component<???>* > myList;
myList.push_back(&mySolenoid);
myList.push_back(&myRFCavity);

list<Component<???>*>::iterator it;

for (int i = 0; i < LargeNumberSteps; i++){
for (int j = 0; j < LargeNumberParticles; j++){
for( it = myList.begin(); it != myList.end(); it++){
(*it).getExternalField(R[j],E,B);
}
}
}

Is this possible to implement without using virtual functions? If yes,
how would this solution look like? Thanks for your help!
 
G

Gianni Mariani

Kraus Christof wrote:
....
Is this possible to implement without using virtual functions? If yes,
how would this solution look like? Thanks for your help!

For each derived type of particle, is it possible to create a separate
list ? In other words, is the order in which getExternalField is called
for each particle significant ?

Are there a finite number of particle types ?
 
D

dp1978x

Hi,
[snip]

With the CRT Pattern I would define a solenoid as
class Solenoid: Component<Solenoid>
{
..

};

Now the problem is that I want to have pointers to objects of these
derived classes in an STL list (not only a list of solenoids, but mixed
with other types). For example

Solenoid mySolenoid; //is derived from Component<Solenoid>
RFCavity myRFCavity; //is derived from Component<RFCavity>

list<Component<???>* > myList;
myList.push_back(&mySolenoid);
myList.push_back(&myRFCavity);

list<Component<???>*>::iterator it;

for (int i = 0; i < LargeNumberSteps; i++){
for (int j = 0; j < LargeNumberParticles; j++){
for( it = myList.begin(); it != myList.end(); it++){
(*it).getExternalField(R[j],E,B);
}
}

}

Is this possible to implement without using virtual functions? If yes,
how would this solution look like? Thanks for your help!

No, each specialization of Component <???> is a *different* type,
regardless of what "???" is. These types have nothing in common (no
common base class) so it's not possible to write code that determines
which version of getExternalField to call dynamically.

There's nothing you can replace the "???" with that will make this
work. The only way to have different types in the same list is by
making sure they are derived from a common base class, which is what
your current solution probably does already.

If you are worried about performance, maybe there are other areas you
can look into. Maybe you can cache the results of getExternalField()
or look into optimizing each version of this function in some other
way.

D.
 
K

kreischtauf

I have only one sort of particles, but about 10-20 electromagnetic
devices. The list should be a list of devices rather than of particles.

Yes in principle it would be possible to have a list for each derived
class of device, and also the order is insignificant. But the lists are
quite short and I guess a lot of performance I gained by not having
virtual functions would be lost again when I have to loop on 10-20 lists
instead of only one. So I probably will keep my virtual functions and
search some other place for improvement. Thanks nevertheless!
 
J

Jerry Coffin

I have only one sort of particles, but about 10-20 electromagnetic
devices. The list should be a list of devices rather than of particles.

Yes in principle it would be possible to have a list for each derived
class of device, and also the order is insignificant. But the lists are
quite short and I guess a lot of performance I gained by not having
virtual functions would be lost again when I have to loop on 10-20 lists
instead of only one. So I probably will keep my virtual functions and
search some other place for improvement. Thanks nevertheless!

This doesn't sound very likely to me. In your original post, you talked
about there being up to a few million calls to the virtual function.

Here you're saying you have only a few dozen (or so) lists to loop
through. Unless looping through the lists is _horribly_ slow, you can
hardly help but come out ahead (probably quite a ways ahead).
 
J

James Kanze

This doesn't sound very likely to me. In your original post,
you talked about there being up to a few million calls to the
virtual function.
Here you're saying you have only a few dozen (or so) lists to
loop through. Unless looping through the lists is _horribly_
slow, you can hardly help but come out ahead (probably quite a
ways ahead).

Maintaining a single list and using virtual functions seems like
a cleaner (i.e. easier to maintain) solution to me. Unless the
overhead of the virtual function calls really does make the
program to slow, I'd stick with it. (The overhead of virtual
function calls depends on a lot of things, and can vary from
almost negligible to very important, depending on the
architecture and the compiler.)
 
J

Jerry Coffin

[ ... ]
Maintaining a single list and using virtual functions seems like
a cleaner (i.e. easier to maintain) solution to me. Unless the
overhead of the virtual function calls really does make the
program to slow, I'd stick with it. (The overhead of virtual
function calls depends on a lot of things, and can vary from
almost negligible to very important, depending on the
architecture and the compiler.)

Oh, I agree that it's generally cleaner. Dismissing it on the theory
that looping through the separate lists would lose as much as you'd gain
from eliminating the virtual function calls seems nearly insupportable
to me though. Obviously I haven't profiled his source code and I don't
even know what architecture he's using, so I can't be _sure_, but the
math just doesn't seem to make much sense. For things to work out as
he's postulated, one of two things would have to be true: either loops
would have to have extremely high overhead, or else virtual functions
would have to have no overhead at all (even a single cycle, repeated a
few million times, would come out to more than I'd expect as the
overhead of looping over a dozen or so lists).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top