FEHLER
-
const double colormap::define_color(const double min, const double max, const double val) const { return (val - min) / (max - min); } void colormap::colormap_funct(color_map const& type) { switch (type) { case colormap::TEMP: calcColorTempColormap(min, max, val); break; case colormap::FARBT: calcColorFARBTONColormap(min, max, val); break; default: throw std::logic_error("Unknown colormap"); } }... s
colormap::colormap(color_map const& type, const double minimum, const double maximum) : minimum(minimum), maximum(maximum) { } int main() { colormap farbskala(colormap::TEMP,200,3000); // ...Aber insgesammt ist der Code stark optimierungsbedürftig!
typedef unsigned char[3] rgb_t; const rgb_t colormap::calcColorTempColormap(const double min, const double max, const double val) { const double tmp(define_color(min, max, val)); rgb_t colors; unsigned char* it(&colors[0]); if (tmp <= 0.333333333333) { // glrot *it++ = 3 * tmp * r; // glgruen *it++ = 0; } else { // glrot *it++ = r; if (tmp <= 0.66666666666) { // glgruen *it++ = g * 3.0 * tmp - 1; // glblau *it = 0; } else { // glgruen *it++ = g; // glblau *it = b * 3.0 * tmp - 2; } } }sollte von der Performance her wesentlich schneller sein als dein Code.
=> Einsparen von Divisionen
=> Iterator(Zeiger in dem Fall) sind schneller als Indexoperatoren
=> POD statt std::vectorconst rgb_t colormap::calcColorFARBTONColormap(const double min, const double max, const double val) { const double tmp(define_color(min, max, val)); rgb_t colors; unsigned char* it(&colors[0]); // glrot if (tmp <= 0.1666666666666666) *it++ = 1; else if (tmp <= 0.333333333333333) *it++ = 1 - (tmp - 0.1666666666666666) / 0.1666666666666666; else if (tmp <= 0.6666666666666) *it++ = 0; else if (tmp < 0.83333333333333) *it++ = (tmp - 0.6666666666666) / 0.1666666666666666; else if (tmp < 1.0) *it++ = 1; else *it++ = 1 - (tmp - 0.1666666666666666) / 0.1666666666666666; // glgruen if (tmp <= 0.3333333333333) *it++ = 0; else if (tmp >= 0.5 && tmp <= 0.83333333333333) *it++ = 1; else if (tmp > 0.83333333333333 && tmp < 1.0) *it++ = 1 - (tmp - 0.83333333333333) / 0.1666666666666666; else *it++ = (tmp - 0.333333333333333) / 0.16666666666666666; // glblau if (tmp < 0.16666666666666) *it = tmp / 0.1666666666666; if (tmp <= 0.5) *it = 1; else if (tmp > 0.666666666666666) *it = 0; else *it = 1 - (tmp - 0.5)/ 0.166666666666666666; return colors; }=> POD statt std::vector (da nunr 3 Werte ...)
=> Umsortieren deiner if-Schachtelung
-> Weniger Vergleiche
=> Iterator(Zeiger)
=> Divisionen raus genommen.
-
An (D)evil
WOW!!!!
Dank dir!!!!!!
Werd erstmal n bissl Zeit brauchen zu verinnerlichen was du da so schnell hingezaubert hast.
Respekt.

Hoffe, dass ich irgendwann auch in den Genuss komme gute Antworten zu geben als ständig nur zu fragen.
-
(D)Evil, für wie blöd hälst du eigentlich die Compiler (bzw. die Entwickler von Compilern)?
Statt deiner Magic-Numbers (0.1666666666666666 !!!) würde ich eher den Code von 'sportsfreund' nehmen.
Besser wäre natürlich noch die Benutzung von benannten Konstanten:const double Third = 1.0/3.0; // etc.
-
(D)Evil schrieb:
Aber insgesammt ist der Code stark optimierungsbedürftig! [ ... ]
Performance [ ... ] => Einsparen von Divisionen [ ... ] => Divisionen raus genommen.~Compilerfreund schrieb:
(D)Evil, für wie blöd hälst du eigentlich die Compiler (bzw. die Entwickler von Compilern)?
=> besser lesen und du kommst selbst auf die lösung...
-
~Compilerfreund schrieb:
(D)Evil, für wie blöd hälst du eigentlich die Compiler (bzw. die Entwickler von Compilern)?
Statt deiner Magic-Numbers (0.1666666666666666 !!!) würde ich eher den Code von 'sportsfreund' nehmen.
Besser wäre natürlich noch die Benutzung von benannten Konstanten:const double Third = 1.0/3.0; // etc.Du hast Recht, dass es voelliger Unsinn ist 0.1666666666666666 anstelle 1.0/6.0 zu schreiben. Aber eine Konstante "Third" zu nennen erinnert mich etwas an einen gewissen Artikel.
-
Christoph schrieb:
Aber eine Konstante "Third" zu nennen erinnert mich etwas an einen gewissen Artikel.

-
(D)Evil schrieb:
typedef unsigned char[3] rgb_t; const rgb_t colormap::calcColorTempColormap(const double min, const double max, const double val) { const double tmp(define_color(min, max, val)); rgb_t colors; unsigned char* it(&colors[0]); if (tmp <= 0.333333333333) { // glrot *it++ = 3 * tmp * r; // glgruen *it++ = 0; } else { // glrot *it++ = r; if (tmp <= 0.66666666666) { // glgruen *it++ = g * 3.0 * tmp - 1; // glblau *it = 0; } else { // glgruen *it++ = g; // glblau *it = b * 3.0 * tmp - 2; } } }sollte von der Performance her wesentlich schneller sein als dein Code.
=> Einsparen von Divisionen
=> Iterator(Zeiger in dem Fall) sind schneller als Indexoperatoren
=> POD statt std::vectorDa ist viel verstecktes Grauen dabei.
Ich vermisse im Übrigen ein return - da bin ich auch sehr gespannt. Bloß weil rgb_t nicht so aussieht, bedeutet nicht, dass Funktionen plötzlich Arrays zurückgeben können.
Es gibt keinen plausiblen Grund, weshalb die Performance von Iteratoren gegenüber Indizierung per se besser oder schlechter sein sollte.
POD statt vector. ja, aber eigentlich heißt es Initialisierung statt komplizierter Zuweisung (dann kann man auch das blau nicht mal eben vergessen, und das Erscheinungsbild wird regelmäßiger).struct rgb_t { unsigned char r,g,b; }; // typedef std::tr1::tuple<uchar,uchar,uchar> rgb_t; rgb_t colormap::calcColorTempColormap(double min, double max, double val) { const double tmp = 3 * define_color(min, max, val); if ( tmp <= 1 ) { rgb_t colors = { tmp * r, 0, 0 }; return colors; } else if ( tmp <= 2 ) { rgb_t colors = { r, g * tmp - 1, 0 }; return colors; } else { rgb_t colors = { r, g, b * tmp - 2 }; return colors; } }nat. nur, wenn die Analyse des ursprünglichen Codes stimmt, ich bin jetzt mal davon ausgegangen, dass die Berechnung (D)Evil ansonsten korrekt ist.
-
Schau mal in Zeile 43!
-
Hmm Indexoperator ist aber langsamer als ein Zeiger.
Indexoperator:
- Startposition des Array nehmen
- Um i Einheiten nach vorne schieben
Zeiger:
- Fertig
Und ja stimmt mit den Magic numbers ist klar... war nur zum vereinfachen ein wenig leichter ... sorry.
Das return hab ich vergessen ... war nur hier reingetippt und nicht getestet ... von d.h. kann es sein das nen paar Fehler drin sind. Es ging mir auch mehr darum, dass da einiges vereinfacht/verbessert werden konnte!
Öhm stimmt im ersten Zweig fehlt mir ein blau ... verflucht ^^
-
und im besten fall hast du einen random-access-iterator und machst dann:
*(i + 1) = ... *(i + 2) = ... *(i + 3) = ...