 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Tino Schumacher Guest
|
Posted: Tue Nov 25, 2003 9:31 am Post subject: Design & Performance Frage |
|
|
Hallo Newsgroup,
ich beschäftige mich gerade mit der Umsetzung von Kartenprojektionen, also
der Transformation von geographischen ( phi, lambda) in rechtwinklige
Koordinaten (x, y).
Hier meine Idee zur Umsetzung (meine Frage ist unten):
class // Basisklasse
CProjection
{
public:
CProjection(){}
virtual ~CProjection(){}
virtual CCoordinate transform( const double& dPhi, const double& dPhi) = 0;
};
class // abgeleitete Klasse für eine Projektion (Beispiel)
CAzimuthalProjection: public CProjection
{
public:
CAzimuthalProjection(){}
virtual ~CAzimuthalProjection(){}
virtual CCoordinate transform( const double& dPhi, const double& dPhi)
{
//Transformationsvorschrift für die entsprechende Transformation
// ....
return (CCoordinate(dX, dY));
}
};
class // Klaase die Projektionen verwendet
CUseCProjection : public CProjection
{
public:
CUseCProjection(const CProjection* ptrProjection)
: m_ptrProjection(ptrProjection) {}
virtual ~CUseCProjection(){}
void doSomeStuff
{
double dPhi = 0.,
dLambda = 0.;
// hier kommen viele, viele Transformationen
// ....
CCoordinate Point;
Point = m_ptrProjection->transform(dPhi , dLambda);
}
private:
CProjection* m_ptrProjection;
};
In dem Programm sollen mehrere Projektionen angebeten werden. Um die
Implementierung so übersichtlich wie möglich zu gestallten und spätere
Erweiterungen zu realisieren, wollte ich jede "neue" Projektion in eine
extra Klasse schreiben.
In dem Projekt sind sehr, sehr viele (!) Transformationsschritte
durchzuführen. Ist das oben dargestellte Design mit dem Zugriff auf eine
gemeinsame Basisklasse (RTTI-Run Time Type Information ) effizient oder ist
einen andere Lösung besser?
Um welchen Faktor würde das Programm schneller, wenn alle Projektionen in
einer gemeinsamen Klasse verwaltet und entsprechen einer
switch/case-Anweisung aufgerufen werden?
Danke Tino
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Wed Nov 26, 2003 12:51 pm Post subject: Re: Design & Performance Frage |
|
|
Tino Schumacher wrote:
| Quote: |
class // Klaase die Projektionen verwendet
CUseCProjection : public CProjection
{
|
das wuerde ich nicht machen. Eine Klasse die eine bestimmte
Projektion benutzt ist selber keine Projektion. So wie ein
Auto zwar einen Motor hat aber selbst eben kein Auto ist.
[snip]
| Quote: |
private:
CProjection* m_ptrProjection;
|
Jetzt bin ich verwirrt. Also doch eine 'hat ein' Beziehung.
Tippfehler?
| Quote: | };
In dem Programm sollen mehrere Projektionen angebeten werden. Um die
Implementierung so übersichtlich wie möglich zu gestallten und spätere
Erweiterungen zu realisieren, wollte ich jede "neue" Projektion in eine
extra Klasse schreiben.
|
Yep.
| Quote: |
In dem Projekt sind sehr, sehr viele (!) Transformationsschritte
durchzuführen. Ist das oben dargestellte Design mit dem Zugriff auf eine
gemeinsame Basisklasse (RTTI-Run Time Type Information ) effizient oder ist
einen andere Lösung besser?
|
Da gibts nur eine Moeglichkeit das rauszufinden: Schreib 2 (vereinfachte)
Versionen und teste sie!
| Quote: |
Um welchen Faktor würde das Programm schneller, wenn alle Projektionen in
einer gemeinsamen Klasse verwaltet und entsprechen einer
switch/case-Anweisung aufgerufen werden?
|
Schneller?
Eher: langsamer.
Der virtual Mechanismus ist mit ziemlicher Sicherheit schneller als alles was
Du 'zu Fuss' selbst implementieren kannst. Aber im Zweifel: ausprobieren.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Frank Thilo Guest
|
Posted: Wed Nov 26, 2003 1:01 pm Post subject: Re: Design & Performance Frage |
|
|
Tino Schumacher <tschumi (AT) cs (DOT) tu-berlin.de> wrote:
: Um welchen Faktor würde das Programm schneller, wenn alle Projektionen in
: einer gemeinsamen Klasse verwaltet und entsprechen einer
: switch/case-Anweisung aufgerufen werden?
Ich gehe davon aus, dass die Entscheidung, welche Projektion verwendet
werden soll, eher selten geschieht und diese Projektion dann auf sehr viele
Einzelpunkte angewendet wird? Somit wäre der polymorphe Dispatch für jeden
einzelnen Punkt eigentlich unnötig. Die Idee wäre dann, diese Entscheidung
vorzulagern. Eine triviale Variante wäre z.B., dass eine virtuelle Funktion
in den ProjektionsKlassen einen Funktionszeiger auf eine statische FUnktion
zurückliefert, etwa:
//////////////
#include <algorithm>
struct base {
typedef double (*transform_func)(double,double);
virtual transform_func get_transform() const=0;
};
struct derived : base
{
static double transform(double a,double b) {return a+b;}
transform_func get_transform() const {return transform;}
};
int main()
{
base *b=new derived;
base::transform_func f=b->get_transform();
const int count=10000;
double data[count];
std::fill(data,data+count,0.0);
for (int i=0;i
data[i]=f(data[i],data[i+1]);
delete b;
}
///////////////
Ich habe dabei das Problem etwas vereinfacht, um das Prinzip zu
verdeutlichen. Der Geschwindigkeitszuwachs bei Verwendung von g++ 3.3 mit
-O3 ist bei obiger einfacher Transform-Operation deutlich (im Vergleich zu
einer virtuellen Transform-Funktion). Warum der Cpmpiler die Optimierung in
diesem einfachen Beispiel nicht selbst vornehmen kann, ist mir allerdings
unklar, evtl. entgeht mir etwas.
Das Beispiel geht weiterhin davon aus, dass die Transform-Funktion nicht von
weiteren Daten abhängt. Ansonsten bietet sich stattdessen ein Funktionsobjekt
an.
Wenn du wirklich pro Datum dynamisch die Auswahl der richtigen Projektion
brauchst, dürfte die Variante mit der direkten virtuellen Funktion wohl
schon das Optimum sein. Ich lasse mich durch Benchmarks aber vom Gegenteil
überzeugen .
--
Frank Thilo - [email]thilo (AT) unix-ag (DOT) org[/email] IRC: Chestal
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Albrecht Fritzsche Guest
|
Posted: Wed Nov 26, 2003 2:04 pm Post subject: Re: Design & Performance Frage |
|
|
Tino Schumacher wrote:
| Quote: | class // Basisklasse
CProjection
{
};
class // abgeleitete Klasse für eine Projektion (Beispiel)
CAzimuthalProjection: public CProjection
{
public:
CAzimuthalProjection(){}
virtual ~CAzimuthalProjection(){}
virtual CCoordinate transform( const double& dPhi, const double& dPhi)
{
//Transformationsvorschrift für die entsprechende Transformation
// ....
return (CCoordinate(dX, dY));
}
};
class CUseCProjection
{
public:
CUseCProjection(const CProjection* ptrProjection)
: m_ptrProjection(ptrProjection) {}
private:
CProjection* m_ptrProjection;
};
|
Koennte ja uU auch durch
class CAzimuthalProjection
{
CCoordinate transform( const double& dPhi, const double& dPhi){}
};
...
template <class Projection>
class CUseProjection
{
private:
Projection mProjection;
};
// for you convenience
typedef CUseProjection<CAzimuthalProjection> UseAzimuth;
...
ersetzt werden. Dies spart Dir dann natuerlich eine Menge evtl Probleme
und ist auf jeden Fall mindestens so schnell, wie Deine beiden
Alternativen. Zudem ware es wahrscheinlich Overkill, wenn Du
tatsaechlich jede Transformation dynamisch mittels new anlegen willst.
| Quote: | In dem Programm sollen mehrere Projektionen angebeten werden. Um die
Implementierung so übersichtlich wie möglich zu gestallten und spätere
Erweiterungen zu realisieren, wollte ich jede "neue" Projektion in eine
extra Klasse schreiben.
In dem Projekt sind sehr, sehr viele (!) Transformationsschritte
durchzuführen. Ist das oben dargestellte Design mit dem Zugriff auf eine
gemeinsame Basisklasse (RTTI-Run Time Type Information ) effizient oder ist
einen andere Lösung besser?
Um welchen Faktor würde das Programm schneller, wenn alle Projektionen in
einer gemeinsamen Klasse verwaltet und entsprechen einer
switch/case-Anweisung aufgerufen werden?
|
Es gibt ja noch andere Varianten, den switch zu vermeiden -
statischer Polymorphismus. Siehe obige Bsp-Implementierung.
Ansonsten musst Du aber beachten, dass die RTTI-Variante
einzig eine zusaetzliche Dereferenzierung pro Projection, dh pro
transform()-Aufruf erfordert. Daher sollte diese Dereferenzierung
im Vergl. zu transform() verschwindend gering und also garnicht
spuerbar sein. Lege daher lieber einen Schwerpunkt darauf, dass
Deine Loesung mit beliebig neuen Projektionen erweitert werden
kann, ohne dass Du Code aendern musst.
Ali
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Albrecht Fritzsche Guest
|
Posted: Wed Nov 26, 2003 3:36 pm Post subject: Re: Design & Performance Frage |
|
|
Rolf Magnus wrote:
| Quote: | Karl Heinz Buchegger wrote:
das wuerde ich nicht machen. Eine Klasse die eine bestimmte
Projektion benutzt ist selber keine Projektion.
Gegenbeispiel:
In dem Zimmer, von dem aus ich poste, liegt viel Krimskrams rum. Teile
davon sind vom Typ "class Dose : public Krimskrams", die durchaus
weiteren Krimskrams enthalten.
Falls sich jemand über das Beispiel wundert: Ich miste gerade aus ;-)
Gegenbeispiel - nur, weil Du viel Krimskrams /nutzt/, dh ausmistest, |
bist Du selbst noch lange kein Krimskrams :-; Zudem gehoert Dein Zimmer
eher in die "Known Uses"-Sektion des Composite.Pattern.
Ansonsten hat Dein Bsp natuerlich nichts mit obigen Beispielen zu tun -
dort ging es um *Use*-Relationen und eben nicht um *Is-A*-Relationen.
Ali
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Wed Nov 26, 2003 4:02 pm Post subject: Re: Design & Performance Frage |
|
|
Karl Heinz Buchegger wrote:
| Quote: | Tino Schumacher wrote:
class // Klaase die Projektionen verwendet
CUseCProjection : public CProjection
{
das wuerde ich nicht machen. Eine Klasse die eine bestimmte
Projektion benutzt ist selber keine Projektion. So wie ein
Auto zwar einen Motor hat aber selbst eben kein Auto ist.
|
Gegenbeispiel:
In dem Zimmer, von dem aus ich poste, liegt viel Krimskrams rum. Teile
davon sind vom Typ "class Dose : public Krimskrams", die durchaus
weiteren Krimskrams enthalten.
Falls sich jemand über das Beispiel wundert: Ich miste gerade aus ;-)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Wed Nov 26, 2003 5:31 pm Post subject: Re: Design & Performance Frage |
|
|
Hallo,
Tino Schumacher wrote:
| Quote: | Hallo Newsgroup,
ich beschäftige mich gerade mit der Umsetzung von Kartenprojektionen, also
der Transformation von geographischen ( phi, lambda) in rechtwinklige
Koordinaten (x, y).
Hier meine Idee zur Umsetzung (meine Frage ist unten): |
| Quote: | In dem Programm sollen mehrere Projektionen angebeten werden. Um die
Implementierung so übersichtlich wie möglich zu gestallten und spätere
Erweiterungen zu realisieren, wollte ich jede "neue" Projektion in eine
extra Klasse schreiben.
|
klingt vernünftig.
| Quote: | In dem Projekt sind sehr, sehr viele (!) Transformationsschritte
durchzuführen. Ist das oben dargestellte Design mit dem Zugriff auf eine
gemeinsame Basisklasse (RTTI-Run Time Type Information ) effizient oder ist
einen andere Lösung besser?
|
Schwer zu sagen, ob es eine besser Lösung gibt, wenn man das Problem
kaum kennt . Gibt es neben sehr vielen Transformationsschritten auch
sehr viele Koordinate die transformiert werden müssen? Wenn ja, sollte
es schon mal effektiver sein, eine Transformation über alle Koordinaten
laufen zu lassen bevor man die nächste Transformation vornimmt.
| Quote: | Um welchen Faktor würde das Programm schneller, wenn alle Projektionen in
einer gemeinsamen Klasse verwaltet und entsprechen einer
switch/case-Anweisung aufgerufen werden?
|
Ich glaube kaum, das das etwas bringt. Anfänger neigen meist dazu,
'lustige' Sachen zu machen, von denen sie glauben, das diese
performanter sind . Die Wahl eines vernünftigen Algorithmus bzw.
Vorgehens hat meist einen viel größeren Einfluß auf die Laufzeit.
Wenn es in Deinem Fall um Transformationen wir Rotation, Translation
usw. geht, könnte es sich lohnen homogene Transformationen zu verwenden.
Dabei erweitert man den zu transformierenden Vector um eine Dimension
und Summiert alle nötigen Transformationen in einer Matrix auf. Den
Vector multipliziert man am Ende dann mit der Matrix, wobei dann alle
Transformationen auf einmal durchgeführt werden.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Tino Schumacher Guest
|
Posted: Fri Nov 28, 2003 9:45 am Post subject: Re: Design & Performance Frage |
|
|
| Quote: | CAzimuthalProjection: public CProjection
|
hier war mein FEHLER!! Das ": public CProjection" muss natürlich weg!!!
Hier ist wohl die BENUTZT-Beziehung besser.
Erst mal danke für die Vorschläge und Anregungen.
Noch mal kurz zum Problem:
die Projektion wird einmal durch den Benutzer zur Laufzeit ausgewählt. d. h.
eine Template-Lösung ist schon nicht möglich.
Weiterhin ist das Problem stark vereinfacht. Die Transformation von
geographischen in kartesische 2D-Koordinaten verläuft über verschiedene
Reihenentwicklungen - je nach Kartenprojektion.
Zusätzlich werden weitere Parameter, wie z.B. Kugel- oder Ellipsoidparameter
benötigt, weshalb es wohl am Besten ist geschickt abzuleiten.
Homogene Koordinaten sind eine feine Sache aber an dieser Stelle wirklich
nicht zu gebrauchen.
Gruss Tino
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Fri Nov 28, 2003 12:48 pm Post subject: Re: Design & Performance Frage |
|
|
Tino Schumacher wrote:
| Quote: |
CAzimuthalProjection: public CProjection
hier war mein FEHLER!! Das ": public CProjection" muss natürlich weg!!!
Hier ist wohl die BENUTZT-Beziehung besser.
|
Aehm. Bist Du Dir da sicher ?
Ich kenne zwar Die Details Deines Pgms nicht, allerdings
spricht schon alleine die Namensgebung dafuer, das Du tatsaechlich
willst:
class CAzimuthalProjection: public CProjection
{
...
};
In normalem Deutsch: 'Eine AzimutalProjektion ist eine (spezielle Form
einer) Projektion'. Macht perfekten Sinn fuer mich.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Tino Schumacher Guest
|
Posted: Mon Dec 01, 2003 11:20 am Post subject: Re: Design & Performance Frage |
|
|
"Karl Heinz Buchegger" <kbuchegg (AT) gascad (DOT) at> schrieb im Newsbeitrag
news:3FC7441F.E4183F35 (AT) gascad (DOT) at...
| Quote: | Tino Schumacher wrote:
CAzimuthalProjection: public CProjection
hier war mein FEHLER!! Das ": public CProjection" muss natürlich weg!!!
Hier ist wohl die BENUTZT-Beziehung besser.
Aehm. Bist Du Dir da sicher ?
Ich kenne zwar Die Details Deines Pgms nicht, allerdings
spricht schon alleine die Namensgebung dafuer, das Du tatsaechlich
willst:
class CAzimuthalProjection: public CProjection
{
...
};
In normalem Deutsch: 'Eine AzimutalProjektion ist eine (spezielle Form
einer) Projektion'. Macht perfekten Sinn fuer mich.
|
Hast natürlich recht. Hab das falsche kopiert.... :-(
CUseCProjection : public CProjection
{/*....*/};
ist FALSCH!!!!!
RICHTIG wäre:
CUseCProjection
{//...
private:
CProjection *m_ptrProjection;
};
Tino
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|