Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Brauche Optimierungshilfe :)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
01.11.2006, 23:29 Uhr
~testo
Gast


Hallo,

die folgende funktion die mit einer struct zusammenarbeitet frisst mir 70% meiner gesamten Laufzeit. Ich habe das mittels callgrind/kcachegrind unter debian linux geprofiled!
Compiler: gcc3.4.3 (ich weiß - net der neueste)

Funktionsweise:
Ich habe eine Matrix in einem vector gespeichert. Die werte sind von oben nach unten und nicht wie üblich von links nach rechts gespeichert - d.h. sie ist SPALTENWEISE gespeichert - d.h. zuerst die werte der ersten spalte, dann der zweiten usw.
Jetzt möchte ich alle ZEILEN der matrix löschen in denen ALLE einträge Null sind. Dies ist schwieriger weil ich ja Spaltenweise gespeichert habe - daran ist leider nix zu ändern.

Mein versuch im moment ist dieser:


C++:
void
myClass::Lösche_alle_Nullzeilen(std::vector< double >& matrix,
                       int& x_dim,
                       int& y_dim,
                       const int col,
                       int& idx)
{
     std::vector< bool >     mask( y_dim );

     for ( int y = 0; y < y_dim; ++y )
     {
         mask[ y ] = true;
         if(y == col)
         {
             mask[ y ] = false;
             continue;
         }
         for ( int x = 0; x < x_dim; ++x )
         {
             if ( matrix[ x * y_dim + y ] != 0 )
             {
                 mask[ y ] = false;
                 break;
             }
         }
     }
        
     matrix.erase( std::remove_if( matrix.begin(),
                   matrix.end(),
                   IS_MASKED( matrix, mask ) ),
     matrix.end() );
    
     y_dim = matrix.size() / x_dim;    
}


//das struct sieht so aus:
struct IS_MASKED
{
     std::vector< bool > mask_;
     const std::vector< double >* erase_el_;
    
     IS_MASKED(const std::vector< double >& erase_el,
               const std::vector< bool >& mask) : erase_el_( &erase_el ),
                                                  mask_( mask )
     {
     }
    
     bool operator()(const double& f) const
     {
         return mask_[ ( &f - &*erase_el_->begin() ) % mask_.size() ];
     }
};



leider wie gesagt dauert das zu lange. Laut meinem callgraphen fressen die iteratoren die meiste Zeit weg - und das aus dieser obigen funktion. Das bedeutet doch aber dass nur das hier:


C++:
matrix.erase( std::remove_if( matrix.begin(),
                   matrix.end(),
                   IS_MASKED( matrix, mask ) ),
     matrix.end() );



für das löschen verantworlich sein kann da nirgendwo sonst iteratoren in dieser funktion verwendet werden....

für änderungsvorschläge oder auch ideen wie man es besser realisieren könnte bin ich sehr dankbar!!!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
02.11.2006, 01:42 Uhr
~testo
Gast


hier ein "unschöner" ansatz der aber bereits einen speedup von 15% und mehr bringt....


C++:
void
myClass::Lösche_Null_Zeilen_OPT(std::vector< double >& matrix,
                               int& x_dim,
                               int& y_dim,
                               const int col,
                               int& idx)
{
     std::vector< double> erg;
     std::vector< double> row_tmp;
     bool insert = false;
     int new_y_dim = 0;
     for(int y = 0; y < y_dim; y++)
     {
         for(int x = 0; x < x_dim; x++)
         {
             if(matrix[x*y_dim + y] != 0)
                 insert = true;
             row_tmp.push_back(matrix[x*y_dim + y ]);
         }  

         if(insert || y == col)
         {
             erg.insert(erg.end(),
                        row_tmp.begin(),
                        row_tmp.end());
             new_y_dim++;
         }

         insert = false;
         row_tmp.clear();
     }
     matrix.clear();
//     transpose
     for(int x = 0; x < x_dim; x++)
     {
         for(int y = 0; y < new_y_dim; y++)
         {
             matrix.push_back(erg[y * x_dim + x]);  
         }
     }
     y_dim = matrix.size() / x_dim;  
}



meric
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.11.2006, 02:00 Uhr
~testo
Gast


Im Grunde genommen ist das Problem so zu betrachten:
wir haben ein Array was mit elementen gefüllt ist und einen integer für die dimension.
die grösse des arrays ist natürlich ganz teilbar durch die dimension.
Bsp:
array: 2 3 0 4 0 0 | 6 7 0 2 0 1 | 3 4 0 0 0 7
dimension = 5 d.h. es gibt also drei spalten in der matrix
und jetzt sollen alle nullzeilen gelöscht werden:
1)
2 3 0 4 0 0 | 6 7 0 2 0 1 | 3 4 0 0 0 7
____|_____________|_____________|

2)
2 3 4 0 0 | 6 7 2 0 1 | 3 4 0 0 7
______|___________|___________|

ergebnis:

2 3 4 0 6 7 2 1 3 4 0 7
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
02.11.2006, 10:19 Uhr
Th



Ich würde anstatt aus dem 'vector' einzelne Werte zu löschen, einfach umgekehrt einen neuen 'vector' erzeugen, welcher aus den nicht leeren Spalten besteht. Vorher am besten mit 'reserve' genügend Speicher bereitstellen, damit beim Einfügen nicht immer wieder Speicher allokiert und Daten umkopiert werden.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
02.11.2006, 23:52 Uhr
~testo
Gast


Danke für die Hilfe....der zweite ansatz von mir verfolgt das mit dem vector erzeugen anstatt löschen ...bringt auch wie beschrieben etwas speedup - aber da geht bestimmt noch viiiiiel mehr....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: