tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von rd4eva
ERLEDIGT
JA
ANTWORTEN
14
ZUGRIFFE
743
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Hallo,
    ich habe ein Performance Problem. Ich lese Remote Verzeichnisse aus und zwar Freigaben auf die ich auch Zugriff habe.Also Berechtigungen ist alles ok. So nun lese ich kleine Verzeichnisse recht schnell aus. Die Dateien werden schnell angezeigt in der View.
    So nun das Problem stoße ich etwa auf ein Verzeichnis welches Bilder beinhaltet die ca 2MB groß sind und dann davon 100MB gesamt,dauert es sehr lang bis die Dateien angezeigt werden. Sie werden nur als Text angezeigt. Es muss schneller gehen , da ich Sie schneller Angezeigt bekomme wenn ich Windows selbst benutze um Sie mir anzuschauen.
    Hier der Code
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    void CVerzeichnisse::dateien_ermmitteln(System::Windows::Forms::ListView^ listview1, System::String^ root )
    {
        try
        {
            listview1->Items->Clear();
            System::IO::DirectoryInfo^ info = gcnew System::IO::DirectoryInfo(root);
            int zaehler = 0;
            zaehler = info->GetFiles()->Length;
            if(zaehler !=0)
            {
                listview1->BeginUpdate();
                for (int i = 0 ; i<zaehler; i++)
                {
                    System::String^ er = info->GetFiles()[i]->ToString();
                    //System::IO::FileInfo^ er = info->GetFiles()[i];
                    listview1->Items->Add(er->ToString());
                }
                listview1->EndUpdate();
            }
        }
        catch(System::UnauthorizedAccessException^ e)
        {
            listview1->Items->Clear();
            MessageBox::Show(e->Message);
        }   
    }
    Hat da einer eine Idee woran es liegt?Listview update mache ich nur aus Gewohnheit kann auch weg, bringt aber an Geschwindigkeit nichts.
    MFG

    Oli

    p.s c++ wie man erkennen kann
    Geändert von paebels (04.10.11 um 09:23 Uhr)
     

  2. #2
    Avatar von rd4eva
    rd4eva rd4eva ist offline Mitglied Brillant
    Registriert seit
    Feb 2003
    Beiträge
    756
    Du rufst völlig unnötigerweise in deiner Schleife jedesmal wieder die GetFiles() Methode auf.
    Es reicht wenn du das ein mal vor dem Loop machst und das zurück gegebene Array durchläufst.

    Schau dir mal das msdn Beispiel an. Dann sollte klar werden was ich meine:
    http://msdn.microsoft.com/en-us/libr...yf24ss.aspx#Y0
    paebels bedankt sich. 
    In order to understand recursion, one must first understand recursion.

  3. #3
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Ich sag mal danke. IEnummerator geht mir halt noch nicht ab
    In C# macht das halt immer die foreach wenn ich mich nicht irre automatisch.

    Alles sieht nun so aus anke für den Anstoß ich war wieder zu dämlich!
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    void CVerzeichnisse::dateien_ermmitteln(System::Windows::Forms::ListView^ listview1, System::String^ root )
    {
        try
        {
            listview1->Items->Clear();
            System::IO::DirectoryInfo^ info = gcnew System::IO::DirectoryInfo(root);
            array<System::IO::FileInfo^>^ er = info->GetFiles();
            int zaehler = 0;
            zaehler = info->GetFiles()->Length;
            if(zaehler != 0)
            {
                listview1->BeginUpdate();
                for (int i = 0 ; i<zaehler ; i++)
                {
                    //System::IO::FileInfo^ er = info->GetFiles()[i];
                    listview1->Items->Add(er[i]->ToString());
                }
                listview1->EndUpdate();
            }
        }
        catch(System::UnauthorizedAccessException^ e)
        {
            listview1->Items->Clear();
            MessageBox::Show(e->Message);
        }   
    }

    Ich glaube man merkt das ich Anfänger bin.
    Geändert von paebels (04.10.11 um 12:02 Uhr)
     

  4. #4
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Hallo

    ich habe leider noch immer Performane Probleme mit der Listview.
    Bei großen Verzeichnissen ist die Anzeige einfach zu langsam im Netzwerk.
    Ich versteh nicht wieso der Explorer hat die Dateien sofort, auch wenn er Sie im Cache hat es müsste bei der Anwendung die ich geschrieben habe auch schneller gehen.
    Sieht wer das Problem im Code************
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    void CVerzeichnisse::dateien_ermmitteln(System::Windows::Forms::ListView^ listview1, System::String^ root )
    {
        try
        {
            System::Collections::Generic::List<System::Windows::Forms::ListViewItem^>^ test = gcnew System::Collections::Generic::List<ListViewItem^>;
            listview1->Items->Clear();
            System::IO::DirectoryInfo^ info = gcnew System::IO::DirectoryInfo(root);
            array<System::IO::FileInfo^>^ file_array = info->GetFiles();
            System::Collections::IEnumerator^ durchlaeufe = file_array->GetEnumerator();
            int zaehler = 0;
            int i = 0;
            zaehler = info->GetFiles()->Length;
            if(zaehler != 0 )
            {
                while(durchlaeufe->MoveNext())
                {
                    ListViewItem^temp = gcnew ListViewItem();
                    temp->Text = file_array[i]->Name->ToString();
                    temp->SubItems->Add(file_array[i]->CreationTime.Date.ToLongDateString());
                    test->Add(temp);
                    i++;
                }
                listview1->Items->AddRange(test->ToArray());    
            }
        }
        catch(System::UnauthorizedAccessException^ e)
        {
            MessageBox::Show(e->Message);
            listview1->Items->Clear();
        }   
    }
    Wieso ich die Daten vorher in eine List schmeisse , es macht das ganze etas schneller die Listview baut sich schneller auf sobald sie die Daten hat. Aber irgendwas muss da komplett im argen sein.Hilfe wäre nett.
    Nachtrag ich rufe die Funktion 2 mal auf einmal mit Lokalenlaufwerken und einmal mit UNC Pfad ich merke auf einer Maschine schon den Unterschied. Wenn ich es im Netzwerk mache wird es schlimmer. Liegts an meinem Code oben oder was mag es sein?Hier der Aufruf links ist Lokal Rechts für UNC Pfad
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    private: System::Void trwFileExplorer_BeforeExpand_left(System::Object^  sender, System::Windows::Forms::TreeViewEventArgs^ e)
                      {
                          if(e->Node->Nodes[0]->Text == "")
                          {
                              System::Windows::Forms::TreeNode^ node = verbindung.verzeichnisse(e->Node);
                          }
                          e->Node->SelectedImageIndex = 3;
                         
                          verbindung.dateien_ermmitteln(listView1,e->Node->FullPath->ToString());
                      }
    private: System::Void trwFileExplorer_BeforeExpand_right(System::Object^  sender, System::Windows::Forms::TreeViewEventArgs^ e)
                      {
                          if(e->Node->Nodes[0]->Text == "")
                          {
                              System::Windows::Forms::TreeNode^ node = verbindung.verzeichnisse(e->Node);
                          }
                          e->Node->SelectedImageIndex = 3;
                         
                          verbindung.dateien_ermmitteln(listView2,e->Node->FullPath->ToString());
                      }
    MfG Oli
    Geändert von paebels (02.11.11 um 20:27 Uhr)
     

  5. #5
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    schonmal geprüft ob nicht durch dateien_ermitteln im BeforeExpand Ereignis ev. das Ereignis erneut geschmissen wird durch hinzufügen der neuen Nodes?


    Ansonsten, kenne mich mit dem managed C++ nicht aus, aber warum verwendest du nicht direkt foreach und gehst komplizierten Weg über Enumerator (sieht mir so aus als wenn dus vom Reflector abgeschaut hast, was der Compiler ausm foreach macht).

    Was auch helfen könnte wäre auf for schleife umzusteigen. Intern macht foreach auch nixs anderes, aber du ersparst dir Funktionionsaufrufe (die internen Enumerationsmethoden und glaube implizites casten).

    Vereinfacht ungefähr so:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    
    for(int i = 0; i< zaehler; i++)
    {
         FileInfo meineDatei = file_array[i];
         ...
         temp.Text = meineDatei.Name;
         ...
         test.Add(temp);
    }

    Ansonsten System.Diagnostics.Stopwatch damit kannst du stoppen wie lange einzelne Programmabschnitte brauchen, und ev. einzelne Programmteile kurz auskommentieren um das Verhalten zu testen.
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  6. #6
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    foreach habe ich in c++ nicht darum enumerator macht vom Prinzip nix anderes als die foreach soweit ich weiß.Ich hatte eine for schleife das war noch lansamer.Aber der erste Tipp den muss ich mal verfolgen. Aber wie kann ich das testen ?
    MfG
    Oli
     

  7. #7
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Am billigsten einfach Breakpoint setzten und schauen ob er erneut reinspringt.

    Zum foreach komisch, sicher, laut google müsste es "for each", also mit Leerzeichen.

    Und ist for wirklich langsamer oder war es langsamer wegen der internen GetFiles Prüfung?
    Denn eigentlich macht foreach intern auch nixs anderen.
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  8. #8
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Mit Breakpoints habe ich ich schon getestet da ist mir nichts aufgefallen . Ja kann auch for each heissen benutze es ja nicht. Doch ist schneller so steht es auch in meinem Buch. In c# ist die for each ja auch schneller. Ich hba ekeien Ahnung mehr wieso das so slow ist.
    Da smit der Zeit habe ich noch nie gemacht! Ich werde jetzt erstmal schalfen gehen habe mir meinen Code gerad zerschossen und mahce morgen weiter.
    Wenn noch wer irgendeien Denkanstoß hat mit Beispiel her damit. Danke im Vorraus.
    Gruß
    Oli
     

  9. #9
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Hallo
    So Tests ergaben meien Funktion ist es nicht die da was falsch macht.
    Es ist abhängig wieviele Dateien in dem Ordner sind über UNC Pfad. Ab 1000 wird es langsam. Nicjt die Größe der Dateien entscheidet, ein Ordner mit 5000 1kb Dateien ist mit der Aufrufnotation c:\testordner sehr fix .Mit dem Aufruf \\Pc\testordner nur noch langsam. Der gleiche Test mit 10 Dateien und einem gesamt Volumen von 100GB ist der Aufruf bei beiden gleich schnell. Wo nun liegt aber das Problem einer Listview mit einem String UNC Pfad? Google hat mir da nicht geholfen. Jemad eine Idee?

    Mfg
    Oli
    Geändert von paebels (03.11.11 um 13:34 Uhr)
     

  10. #10
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Ok habe die Lösung wohl ,es liegt schlichtweg an der Listview eine Gridview ist 100mal schneller . Habe es getestet mit stopwatch. Und auch andere bestätigen dies. Da sgilt aber nicht für die Listview C# wpf diese ist wiederum schneller. Wieso die Listview langsamer wird beim unc Pfad habe ich nicht herausgefunden aber es ist egal habe die Ansicht auf 100 beschränkt und so mit eine gute Performance
     

  11. #11
    Avatar von colblake
    colblake colblake ist offline Mitglied Gold
    Registriert seit
    Jan 2004
    Ort
    dresden
    Beiträge
    214
    Hallo paebels,

    ich kenn mich in VCPP nicht aus, aber würde doch noch eine Anmerkungen zu deinem Code machen:

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    
     while(durchlaeufe->MoveNext())
                {
                    ListViewItem^temp = gcnew ListViewItem();
                    temp->Text = file_array[i]->Name->ToString();
                    temp->SubItems->Add(file_array[i]->CreationTime.Date.ToLongDateString());
                    test->Add(temp);
                    i++;
                }

    Ich würde erwarten, dass es von dem IEnumerator "durchlaufe" irgendsowas gibt wie durchlaufe->Current, der das aktuelle Listitem zurück gibt.
    Wenn Du, wie in deinem Beispiel, jedesmal den Indexer benutzt "file_array[i]" kannst du auch die for-schleife lassen. Außerdem kostet der Zugriff auf den Indexer mehr Zeit.

    Sorry fürs Klug******en.
     
    Über so viele Sachen wächst Gras , man kann keiner Wiese mehr trauen.

  12. #12
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.504
    Hi

    kann zwar aus dem Kopf auch nicht sagen, wie das Enumerator-Wert-Abfragn genau heißt,
    aber ja, das gibts. Enumerator und Index durchmischen ist auch ziemlich sinnlos, ja.

    Aber die Schnelligkeit ist ganz ohne Enumerator wahrscheinlich am größten.
    Nur ein for mit einem Zähl-int, und Indexzugriff.
    Da muss keine Enumeratorinstanz angelegt werden,
    kein GC diese wieder wegräumen etc. etc.

    Und "VCPP" nennt sich übrigens C++/CLI.
    Das normale C++ gibts trotzdem auch weiterhin in Visual Studio.

    Gruß
     
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  13. #13
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Danke für die Antworten, nur löst das alles nicht auf.Das alles mit einem normalen Pfad bis zu 100mal schneller ist, als wenn man einen UNC Pfad benutzt der aber auf das lokale Laufwerk zeigt wie der normale pfad. Es darf keinen Unterschied geben, da da sSystem auch keinen macht.
    MfG
    oli
     

  14. #14
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Zitat Zitat von colblake Beitrag anzeigen
    Hallo paebels,

    ich kenn mich in VCPP nicht aus, aber würde doch noch eine Anmerkungen zu deinem Code machen:

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    
     while(durchlaeufe->MoveNext())
                {
                    ListViewItem^temp = gcnew ListViewItem();
                    temp->Text = file_array[i]->Name->ToString();
                    temp->SubItems->Add(file_array[i]->CreationTime.Date.ToLongDateString());
                    test->Add(temp);
                    i++;
                }

    Ich würde erwarten, dass es von dem IEnumerator "durchlaufe" irgendsowas gibt wie durchlaufe->Current, der das aktuelle Listitem zurück gibt.
    Wenn Du, wie in deinem Beispiel, jedesmal den Indexer benutzt "file_array[i]" kannst du auch die for-schleife lassen. Außerdem kostet der Zugriff auf den Indexer mehr Zeit.

    Sorry fürs Klug******en.
    Wie arbeite ich denn dann mit dem Objekt aus der Liste weiter wenn ich Current benutzen will. Habe ich noch nie gemacht.
    MFG
    Oli
     

  15. #15
    paebels paebels ist offline Mitglied Gold
    Registriert seit
    Aug 2011
    Beiträge
    100
    Hallo
    ich habe es eh nochmal gegändert in in eine for each aber auch dies eist einfach nicht schneller.
    Der Klotz ist immer die selbe Stelle
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    for each(FileInfo^ files in file_array)
                {
                    ListViewItem^ temp = gcnew ListViewItem();
                    temp->Text = files->Name->ToString();
                    temp->SubItems->Add(files->CreationTimeUtc.ToShortDateString());
                    temp->SubItems->Add(files->Length.ToString()+" "+"Bytes");
                    temp->SubItems->Add(files->Extension->ToString());
    Und zwar an der Stelle wo ist die Subitmes anfüge wirds z.B in System32 argh langsam. Zumindest über ubc Pfad.
    Gruß Oli
     

Ähnliche Themen

  1. Apache DocumentRoot im Netzwerk - Performance?
    Von KICK im Forum Hosting & Webserver
    Antworten: 0
    Letzter Beitrag: 21.07.07, 19:43
  2. Netzwerk-Performance
    Von C-H im Forum Netzwerke
    Antworten: 1
    Letzter Beitrag: 16.04.07, 18:16
  3. Probleme mit Netzwerk Performance
    Von Timo Rickert im Forum Netzwerke
    Antworten: 1
    Letzter Beitrag: 03.03.05, 11:35
  4. MySQL - zu viele Abfragen bzw. Performance verbessern
    Von fercules im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 29.04.04, 12:09
  5. Antworten: 3
    Letzter Beitrag: 29.04.04, 12:09