4 Stimmen

Char* vs. String Geschwindigkeit in C++

Ich habe ein C++-Programm, das Daten aus einer Binärdatei einliest, und ursprünglich habe ich die Daten in std::vector<char*> data . Ich habe meinen Code dahingehend geändert, dass ich jetzt Strings anstelle von char* verwende, so dass std::vector<std::string> data . Einige Änderungen, die ich vornehmen musste, waren der Wechsel von strcmp a compare zum Beispiel.

Ich habe jedoch festgestellt, dass sich meine Ausführungszeit drastisch verlängert hat. Für eine Beispieldatei benötigte ich bei Verwendung von char* 0,38s und nach der Konvertierung in string 1,72s auf meinem Linux-Rechner. Ein ähnliches Problem habe ich auf meinem Windows-Rechner beobachtet, wo die Ausführungszeit von 0,59s auf 1,05s anstieg.

Ich glaube, dass diese Funktion die Ursache für die Verlangsamung ist. Sie ist Teil der Konverterklasse, beachten Sie die privaten Variablen, die mit _ am Ende des Variablennamens. Ich habe hier eindeutig Speicherprobleme und stecke zwischen C- und C++-Code fest. Ich möchte, dass dies C++-Code ist, also habe ich den Code unten aktualisiert.

I Zugang ids_ y names_ viele Male in einer anderen Funktion, daher ist die Zugriffsgeschwindigkeit sehr wichtig. Durch die Erstellung eines map anstelle von zwei separaten Vektoren, konnte ich schnellere Geschwindigkeiten mit stabilerem C++-Code erreichen. Vielen Dank an alle!

Beispiel NewList.Txt

2515    ABC 23.5    32  -99 1875.7  1  
1676    XYZ 12.5    31  -97 530.82  2  
279  FOO 45.5    31  -96  530.8  3  

OLD-Code:

void converter::updateNewList(){
    FILE* NewList;
    char lineBuffer[100];
    char* id = 0;
    char* name = 0;

    int l = 0;
    int n;

    NewList = fopen("NewList.txt","r");
    if (NewList == NULL){
        std::cerr << "Error in reading NewList.txt\n";
        exit(EXIT_FAILURE);
    } 

    while(!feof(NewList)){
        fgets (lineBuffer , 100 , NewList); // Read line    
        l = 0;
        while (!isspace(lineBuffer[l])){
            l = l + 1;
        }

        id = new char[l];
        switch (l){
            case 1: 
                n = sprintf (id, "%c", lineBuffer[0]);
                break;
            case 2:
                n = sprintf (id, "%c%c", lineBuffer[0], lineBuffer[1]);
                break;
            case 3:
                n = sprintf (id, "%c%c%c", lineBuffer[0], lineBuffer[1], lineBuffer[2]);        
                break;
            case 4:
                n = sprintf (id, "%c%c%c%c", lineBuffer[0], lineBuffer[1], lineBuffer[2],lineBuffer[3]);
                break;
            default:
                n = -1;
                break;
        }
        if (n < 0){
            std::cerr << "Error in processing ids from NewList.txt\n";
            exit(EXIT_FAILURE);
        }

        l = l + 1;
        int s = l;
        while (!isspace(lineBuffer[l])){
            l = l + 1;
        }
        name = new char[l-s];
        switch (l-s){
            case 2:
                n = sprintf (name, "%c%c", lineBuffer[s+0], lineBuffer[s+1]);
                break;
            case 3:
                n = sprintf (name, "%c%c%c", lineBuffer[s+0], lineBuffer[s+1], lineBuffer[s+2]);
                break;
            case 4:
                n = sprintf (name, "%c%c%c%c", lineBuffer[s+0], lineBuffer[s+1], lineBuffer[s+2],lineBuffer[s+3]);
                break;
            default:
                n = -1;
                break;
        }
        if (n < 0){
            std::cerr << "Error in processing short name from NewList.txt\n";
            exit(EXIT_FAILURE);
        }

        ids_.push_back ( std::string(id) );
        names_.push_back(std::string(name));
    }

    bool isFound = false;
    for (unsigned int i = 0; i < siteNames_.size(); i ++) {
        isFound = false;
        for (unsigned int j = 0; j < names_.size(); j ++) {
            if (siteNames_[i].compare(names_[j]) == 0){
                isFound = true;
            }
        }
    }

    fclose(NewList);
    delete [] id;
    delete [] name;
}

C++ CODE

void converter::updateNewList(){
    std::ifstream NewList ("NewList.txt");

    while(NewList.good()){
        unsigned int id (0);
        std::string name;

        // get the ID and name
        NewList >> id >> name;

        // ignore the rest of the line
        NewList.ignore( std::numeric_limits<std::streamsize>::max(), '\n');

        info_.insert(std::pair<std::string, unsigned int>(name,id));

    }

    NewList.close();
}

UPDATE: Folgefrage: Engpass beim Vergleich von Zeichenketten und danke für die sehr nützliche Hilfe! Ich werde diese Fehler in Zukunft nicht mehr machen!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X