 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Thomas Thiele Guest
|
Posted: Mon Mar 26, 2007 5:54 pm Post subject: inline - Design Frage |
|
|
Hallo zusammen,
ich wollte mal wissen wie man folgende Anforderungen richtig designed.
Mir kommt alles irgendwie krampfig vor, mir fällt aber auch nichts
passendes ein. Die Aufgabe ist am konkreten Beispiel gestellt, mir
geht es aber mehr um die prinzipielle Lösung. Nicht ob inline im
speziellen Anwendungefall wirklich die erhofften Performance-
Steigerung bringt.
Also, ich habe eine Klasse Work, in der es eine Funktion
calculateImage() gibt. Die Übergabeparameter (pointer auf Bilddaten,
Bildgröße, Farbraum etc.) existieren, sind aber nicht von Belang,
daher weggelassen. Im wesentlich besteht die Funktion aus einer for-
schleife über alle Pixel in der eine Funktion einer anderen Klasse
ColorServices aufgrufen wird. Diese Funktion colorConversion3() sollte
inline sein.
ColorServices.h
-----------------------------------------
class ColorServices{
public:
ColorServices();
void colorConversion1(unsigend char &r, unsigend char &g, unsigend
char &b);
static void colorConversion2(unsigend char &r, unsigend char &g,
unsigend char &b);
static void colorConversion3(unsigend char &r, unsigend char &g,
unsigend char &b);
};
-----------------------------------------------
Work.h
----------------------------------------------------------
#inlcude "ColorServices.h"
class Work{
public:
//.....
void calculateImage(/* egal */);
};
--------------------------------------------------------
Work.cpp
-----------------------------------------------------------------------
#include "Work.h"
#include "ColorServicesInline.cpp" //siehe unten
void Work::calculateImage(){
unsigend char r,g,b;
//...irgendwas
for (unsigend int i = 0; i < anzahlpixel; i++){
//r,g,b auslesen, nicht gezeigt
ColorServices::colorConversion3(r,g,b); //<- funktionsaufruf soll
inline sein können
//r,g,b schreiben, nicht gezeigt
}
}
-----------------------------------------------------------------------
ColorServices.cpp
----------------------------------------------
#include "ColorServices.h"
void colorConversion1(unsigend char &r, unsigend char &g, unsigend
char &b){
// r,g,b umrechnen, egal wie
}
void colorConversion2(unsigend char &r, unsigend char &g, unsigend
char &b){
// r,g,b umrechnen, egal wie
}
-----------------------------------------------------------------------
So, jetzt das Problem.
Wenn ich die inline - Funktion colorConversion3() in
ColorServices.cpp implementiere, wird sie von Linker nicht gefunden.
Implementiere ich sie im Header ColorServices.h darf genau ein Modul
ColorServices.h inkludieren
ansonsten beschwert sich der Linker über doppeltes Vorhandensein.
Implementiere ich die Funktion in Work.cpp dann implementiere ich sie
da wo sie gar nicht hingehört.
Ich habe es so gelöst, dass ich ein neues File ColorServicesInline.cpp
angelegt habe, mit der implementierung der inline-Funktion und diese
in work.cpp inkludiere.
Erscheint mir aber auch krampfig.
Was würdet ihr machen?
(die Antwort "auf inline vezichten" zählt nicht... )
Gruß Thomas |
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Sat Mar 31, 2007 1:22 am Post subject: Re: inline - Design Frage |
|
|
Thomas Thiele schrieb:
| Quote: | Wenn ich die inline - Funktion colorConversion3() in
ColorServices.cpp implementiere, wird sie von Linker nicht gefunden.
|
Natürlich wird sie, Du mußt sie nur übersetzen und linken lassen.
| Quote: | Implementiere ich sie im Header ColorServices.h darf genau ein Modul
ColorServices.h inkludieren
|
Das stimmt nicht, vorausgesetzt, Du deklarierst sie als `inline`.
Also entweder direkt in der Klassendefinition oder mit dem
Schlüsselwort `inline` vor der Funktionsdefinition (im Header-File).
MfG |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sat Mar 31, 2007 2:20 am Post subject: Re: inline - Design Frage |
|
|
"Thomas Thiele" <jana.luetz (AT) gmx (DOT) de> writes:
| Quote: | Wenn ich die inline - Funktion colorConversion3() in
ColorServices.cpp implementiere, wird sie von Linker nicht gefunden.
Implementiere ich sie im Header ColorServices.h darf genau ein Modul
ColorServices.h inkludieren
ansonsten beschwert sich der Linker über doppeltes Vorhandensein.
|
Nicht, wenn sie wirklich inline ist und der Compiler und der Linker
etwas taugen. |
|
| Back to top |
|
 |
Andre Poenitz Guest
|
Posted: Sat Mar 31, 2007 12:22 pm Post subject: Re: inline - Design Frage |
|
|
Thomas Thiele <jana.luetz (AT) gmx (DOT) de> wrote:
Hallo Thomas.
| Quote: | ColorServices.h
-----------------------------------------
class ColorServices{
public:
ColorServices();
void colorConversion1(unsigend char &r, unsigend char &g, unsigend
char &b);
|
Bei 'kleinen' Typen wie char ist Uebergabe als Wert in der Regel
preformanter als Uebergabe als Referenz.
Andre' |
|
| Back to top |
|
 |
Thomas Thiele Guest
|
Posted: Sat Mar 31, 2007 7:44 pm Post subject: Re: inline - Design Frage |
|
|
Thomas Maeder schrieb:
| Quote: | Nicht, wenn sie wirklich inline ist und der Compiler und der Linker
etwas taugen.
|
Danke für die Antworten. Also habe ich oder der Compiler was falsch
gemacht. Hmmm.
Dachte eigentlich ich hätte alle Varianten probiert.
Muss ich halt nochmal probieren. |
|
| Back to top |
|
 |
Thomas Thiele Guest
|
Posted: Sat Mar 31, 2007 7:47 pm Post subject: Re: inline - Design Frage |
|
|
Andre Poenitz schrieb:
| Quote: | Bei 'kleinen' Typen wie char ist Uebergabe als Wert in der Regel
preformanter als Uebergabe als Referenz.
|
Das mag sein. Nur erlaubt C++ halt nur einen Rückgabewert pro
Funktion.
Aber daraus ergibt sich eine Interessante Frage, ist eventuell die
Variante mit Wertübergabe und einem Rückgabeobjekt (Z.B. ein char
Array. Oder ein einfacher struct.) mit drei chars performanter also
die Variante mit Referenzen? |
|
| Back to top |
|
 |
Andre Poenitz Guest
|
Posted: Sun Apr 01, 2007 10:47 am Post subject: Re: inline - Design Frage |
|
|
Thomas Thiele <jana.luetz (AT) gmx (DOT) de> wrote:
| Quote: | Andre Poenitz schrieb:
Bei 'kleinen' Typen wie char ist Uebergabe als Wert in der Regel
preformanter als Uebergabe als Referenz.
Das mag sein. Nur erlaubt C++ halt nur einen R?ckgabewert pro
Funktion.
Aber daraus ergibt sich eine Interessante Frage, ist eventuell die
Variante mit Wert?bergabe und einem R?ckgabeobjekt (Z.B. ein char
Array. Oder ein einfacher struct.) mit drei chars performanter also
die Variante mit Referenzen?
|
Haengt vom Compiler ab. Im Zweifelsfall musst Du's ausprobieren.
Ich wuerde erwarten, dass eine struct mit drei chars in der Regel
schneller als Wert uebergeben (bzw. zurueckgegeben) wird als drei
individuelle Zeichen.
Andre' |
|
| Back to top |
|
 |
Andre Poenitz Guest
|
Posted: Sun Apr 01, 2007 11:25 am Post subject: Re: inline - Design Frage |
|
|
Thomas Thiele <jana.luetz (AT) gmx (DOT) de> wrote:
| Quote: | Andre Poenitz schrieb:
Bei 'kleinen' Typen wie char ist Uebergabe als Wert in der Regel
preformanter als Uebergabe als Referenz.
Das mag sein. Nur erlaubt C++ halt nur einen R?ckgabewert pro
Funktion.
Aber daraus ergibt sich eine Interessante Frage, ist eventuell die
Variante mit Wert?bergabe und einem R?ckgabeobjekt (Z.B. ein char
Array. Oder ein einfacher struct.) mit drei chars performanter also
die Variante mit Referenzen?
|
Unwissenschaftlicher Test, dass ich im konkreten Fall Unsinn empfohlen
habe:
color.{h,cpp}:
#include <iostream>
struct color
{
color() { a = b = c = 0; }
int a, b, c;
};
void foo(int & a, int & b, int & c)
{
int i = 1;
a += i;
b += i;
c += i;
}
color bar(color col)
{
int i = 1;
col.a += i;
col.b += i;
col.c += i;
return col;
}
void baz(color & col)
{
int i = 1;
col.a += i;
col.b += i;
col.c += i;
}
test.cpp:
int main(int argc, char * argv[])
{
color col;
int n = 2000 * 1000 * 1000;
switch (argc) {
case 1:
for (int i = 0; i < n; ++i)
foo(col.a, col.b, col.c);
std::cout << "ref: " << col.a + col.b + col.c << std::endl;
break;
case 2:
for (int i = 0; i < n; ++i)
col = bar(col);
std::cout << "copy: " << col.a + col.b + col.c << std::endl;
break;
case 3:
for (int i = 0; i < n; ++i)
baz(col);
std::cout << "ref2: " << col.a + col.b + col.c << std::endl;
break;
}
}
ergibt:
| Quote: | g++ --version
g++ (GCC) 4.1.2 [...] |
| Quote: | g++ -O3 test.cpp color.cpp -o test ; time ./test
ref: 1705032704 |
real 0m19.823s
user 0m19.585s
sys 0m0.012s
| Quote: | g++ -O3 test.cpp color.cpp -o test ; time ./test x
copy: 1705032704 |
real 0m29.280s
user 0m29.086s
sys 0m0.024s
| Quote: | g++ -O3 test.cpp color.cpp -o test ; time ./test x x
ref2: 1705032704 |
real 0m15.090s
user 0m15.041s
sys 0m0.012s
Selbst
color bar2(const color & col)
{
int i = 1;
return color(col.a + i, col.b + i, col.c + i);
}
gibt noch:
real 0m24.166s
user 0m24.078s
sys 0m0.012s
Ganze struct als einzelne Referenz scheint am schnellsten zu sein.
Andre' |
|
| 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
|
|