AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi FOR oder WIHLE was ist schneller (Stringgrid befüllen)

FOR oder WIHLE was ist schneller (Stringgrid befüllen)

Ein Thema von Stef_One · begonnen am 15. Feb 2009 · letzter Beitrag vom 19. Feb 2009
Antwort Antwort
Seite 1 von 3  1 23   
Stef_One

Registriert seit: 5. Sep 2007
18 Beiträge
 
#1

FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 12:13
Hallo zusammen,

kann mir jemand von euch sagen was schneller ist FOR oder WHILE Schleifen ich bin gerade dabei mein Programm zu optimieren.
Dabei werden mehrere Schleifen durchlaufen und die aufbereiteten Ergebnisse dann in einem Sringgrid dargestellt. Momentan stoße ich dabei auf Performance Probleme, ich habe auch schon probiert eine BeginUpdate/EndUpdate einzubauen allerdings scheint das mit einem Stringgrid nicht so einfach zu funktionieren wie mit einer Treeview oder Listbox-Komponente alternativ dazu setzte ich den RowCount des Stringgrid jetzt erst zum Schluss nach der For-Schleife auf den richtigen Wert.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.802 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 12:21
For ist m.W als While-Schleife implementiert. es sollte dann eigentlich keinen Unterschied zwischen den beiden Varianten geben
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.578 Beiträge
 
#3

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 12:21
Wenn du bereits vorher weist, wie oft die Schleife ausgeführt werden muss, ist die for-Schleife besser.

Wobei das im Endeffekt egal sein dürfe da iirc die for-Schleife intern in eine While-Schleife umgewandelt wird. Aber evtl. kann der Compiler dadurch noch etwas optimieren da die Zählervariable nicht verändert werden kann ...

Aber wenn dich der Geschwindigkeitsunterschied interessiert, optimierst du wahrscheinlich an der falschen Stelle

Um das Halbwissen perfekt zu machen:

Delphi-Quellcode:
for i := 0 to 5 do
begin
// ...
end;
wird zu
Delphi-Quellcode:
i := 5;
while(i <> 0)
begin
// ...
dec(i);
end;
  Mit Zitat antworten Zitat
Te7Ris

Registriert seit: 18. Mai 2005
9 Beiträge
 
#4

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 12:28
Hallo,

überleg erstmal ob du dir nicht die ein oder andere verschachtelte Schleife komplett sparen
kannst, da hier der größte "Zeitverschleiß" auftritt...

ansonsten kannste noch probieren, die Ergebnisse erst in ein Array zwischenzuspeichern und dann
nach dem durchlaufen der Schleifen auszugeben... da das "auf den Bildschirm schreiben" länger
dauert als man vermuten würde...


Gruß Maxi
  Mit Zitat antworten Zitat
Stef_One

Registriert seit: 5. Sep 2007
18 Beiträge
 
#5

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 12:33
@Te7Ris: ja dem Problem wollte ich schon aus dem Weg gehen indem ich den Row Count des Stinggrid erst nach der Schleife setze, allerdings bringt das kein Effekt, nach unnötige Verschachtelungen hab ich auch bereits gesucht allerdings ist da jetzt nicht mehr alt soviel rauszuholen.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#6

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 13:01
Da das Befüllen eines Stringgrids ca. 10.00.000x mehr Performance verbrät als ein eventuell vorhandener Unterschied zwischen FOR- und WHILE-Schleife kannst Du dich getrost auf andere Sachen konzentrieren.

Z.B. das allseits beliebte: "Trenne Funktion und Darstellung". Verwende also kein Stringgrid, um 100-Tausende von Daten im Speicher zu halten. Da wird sowieso niemals jemand durchscrollen. Verwende ein Grid nur zur Darstellung eines Ausschnittes deiner Tabelle, so wie z.B. das TDBGrid, das einen kleinen Ausschnitt aus einer beliebig großen Datenmenge (TDataset) zeigt.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Stef_One

Registriert seit: 5. Sep 2007
18 Beiträge
 
#7

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 13:12
@alzaimar: ja das ist bereits schon so, alle daten die ich brache sind in records gespeichert, im stringgrid werden sie nur aufbereitet angezeigt!
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#8

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 13:23
Das liegt ja nur an der Anzeige. Die ist grottenlahm. Mache das mal so :

Sg.hide;
Füllen
Sg.show;
Gruß
Hansa
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 13:54
Zeig mal ein wenig Code. Wie gesagt, ich vermute, Du hast einfach zu viele Records. Hier wäre der Einsatz eines TDatasets und TDBGrid wohl angebracht. Alternativ könntest Du eine TListView im OwnerData-Modus laufen oder nimmst gleich ein TVirtualTreeView, das dafür besonders geeignet ist.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Stef_One

Registriert seit: 5. Sep 2007
18 Beiträge
 
#10

Re: FOR oder WIHLE was ist schneller (Stringgrid befüllen)

  Alt 15. Feb 2009, 14:22
Also das ganze ist ein Tool für meinen Arbeitgeber zur Planung von Schichtplänen, leider ist die Sache schon soweit fotgeschritten das es jetzt nicht so einfach ist hier ein paar Codefetzen hinzuwerfen

Also das Stringgrid ist so aufgebaut



Kostenstelle Arbeitsplatzgruppe Name Personnummer Schicht 1.1 2.1 3.1 4.1 .....das ganze für 4 Wcohen



im Testmodus sind 45 Mitarbeiter eingepflegt
der Record dafür sieht so aus

Delphi-Quellcode:
type
    TData = record
     Name : String[20];
     Vorname : String[15];
     Personalnummer : String[15];
     Kostenstelle : String[15];
     Arbeitsplatzgruppe : String[16];
     Ersthelfer : Boolean;
     Vorarbeiter : Boolean;
     Leiharbeiter : Boolean;
     Username : String[20];
     Telefonnummer : String[20];
     Meister : Boolean;
     Schicht : String[60];
     StartSchicht : String[2];
     Start_Date : String[20];
     ErlaubteKST : String[255];
     EinsatzMoeglichkeit : String[255];
end;
dann get es weiter mit einen "Übersteuern" Record
wird benötigt um Änderungen im Schitplan anzuzeigen
und nicht die eigentlichen Schicht abändern zu müssen
so das der einzelne Mitarbeiter immer im gleichen Rhythmus bleibt

Delphi-Quellcode:
type
    TChangeData = record
     SchichtTyp : String[5];
     Datum : TDateTime;
     Personalnummer : String[15];
     Kostenstelle : String[15];
     Arbeitsplatzgruppe : String[15];
     Wochenweise : Boolean;
end;

type
    TUebersteuern = record
       Daten : Array [1..100000] of TChangeData;
       Count :integer;
end;

die function um die schichten zu berechnen sieht so aus

Delphi-Quellcode:
function GetSchicht(Mitarbeiter:TData;KW:Integer;Year:Integer;Datum:TDateTime;Weekly:Boolean):String;
var
      SchichtSystem :String;
      EinzelSchicht :String;
      EinzelSchichtTag :String;
      i,x :integer;
     // savepos :integer;
      SchichtList :TStringList;
      ErrechnetesDatum :TDateTime;
      EndDatum :TDateTime;
      Tagessumme :Integer;
      y :Integer;
      //5tagesansicht übersteuert in wochenansicht
      q :Integer;
      SaveDate :Tdatetime;
      SaveSchicht :String;
      tagecounter :Integer;
begin

      if mitarbeiter.Schicht='then exit;

      SchichtList:= TStringList.Create;
      //+++++++Schichtsystem des Mitarbeiters suchen++++++++++
      for i:=1 to Settings.SchichtenCount do
       begin
        if Mitarbeiter.Schicht=settings.Schichten[i].Name then
           begin
              SchichtSystem:=settings.Schichten[i].Reihenfolge;
              break;
           end;
       end;

      //+++++++Schichtsystem auseinander flücken
        for i:=1 to Length(SchichtSystem) do
        begin
          if SchichtSystem[i]<>';then
            begin
               EinzelSchicht:=EinzelSchicht+SchichtSystem[i];
            end else
            begin
              SchichtList.Add(EinzelSchicht);
              //main_window.ListBox1.Items.Add(EinzelSchicht) ;
              EinzelSchicht:='';
            end;
        end;

      //Anfangschichtsystem finden mit x vergleichen gegen hinterlegten string
      x:=StrtoInt(Mitarbeiter.StartSchicht)-1;

        //################################## Ansicht Tageweise/Wochenweise #################################
        //################################## Ansicht Tageweise/Wochenweise #################################

        //Tage pro schicht ermitteln und ab startdatum rechnen
        Tagessumme:=0;
        ErrechnetesDatum:=0;
        if Weekly=true then Datum:=StartOfAWeek(Year, KW, 1); //noch end datum eintragen errechtet aus der kw

        while ErrechnetesDatum <= Datum do
          begin
              EinzelSchichtTag:=SchichtList.Strings[x];

              EinzelSchichtTag:=StringReplace(EinzelSchichtTag,'N','', [rfReplaceAll]);
              EinzelSchichtTag:=StringReplace(EinzelSchichtTag,'S','', [rfReplaceAll]);
              EinzelSchichtTag:=StringReplace(EinzelSchichtTag,'F','', [rfReplaceAll]);
              EinzelSchichtTag:=StringReplace(EinzelSchichtTag,'W','', [rfReplaceAll]);

              Tagessumme:=Tagessumme+StrToInt(EinzelSchichtTag);
              ErrechnetesDatum:=StrToDate(Mitarbeiter.Start_Date)+Tagessumme;


              if pos('F',SchichtList.Strings[x])>0 then result:='F';//'Frühschicht';
              if pos('S',SchichtList.Strings[x])>0 then result:='S';//'Spätschicht';
              if pos('N',SchichtList.Strings[x])>0 then result:='N';//'Nachtschicht';
              if pos('W',SchichtList.Strings[x])>0 then result:='.';//'Wochenende';

              inc(x);
              if x> SchichtList.Count-1 then x:=0;
         end;
         //++++++++++++++++++++++++++++Wochenende setzten++++++++++++++++++++++++++++++
         if Weekly=false then if DayOfTheWeek(Datum)>5 then result:='.'; /////
         //++++++++++++++++++++++++++++Wochenende setzten++++++++++++++++++++++++++++++

         

              //##############################Übersteuern Start#################################
              //################################################################################
              for y:=1 to Uebersteuern.Count do
                  begin
                     if Uebersteuern.Daten[y].Personalnummer=Mitarbeiter.Personalnummer then
                        begin

                          if Uebersteuern.Daten[y].Wochenweise=true then
                              begin

                                   if weekly=true then //ansicht in KW
                                     begin
                                       if (Uebersteuern.Daten[y].Datum=StartOfAWeek(Year, KW, 1)) then result:=Uebersteuern.Daten[y].SchichtTyp;
                                     end else
                                     begin //ansicht Tageweise buchung alle 5 arbeitstage!
                                       if (Uebersteuern.Daten[y].Datum<=Datum) and (Uebersteuern.Daten[y].Datum+4>=Datum) then
                                          result:=Uebersteuern.Daten[y].SchichtTyp;
                                     end;

                               end else
                               begin
                                     //tagesansicht
                                     if weekly=false then
                                      begin
                                        if Uebersteuern.Daten[y].Datum=Datum then result:=Uebersteuern.Daten[y].SchichtTyp;
                                      end else
                                      begin
                                      //wochenasicht gucken ob 5 gleiche einträge vorhanden sind
                                        if Uebersteuern.Daten[y].Datum=Datum then
                                          begin
                                             SaveDate:=StartOfTheWeek(Uebersteuern.Daten[y].Datum);
                                             SaveSchicht:=Uebersteuern.Daten[y].SchichtTyp;
                                             tagecounter:=0;
                                             q:=1;

                                          //nochmal die daten durchsuchen für einträge in gleicher woche mit gleicher schicht
                                          while q<=Uebersteuern.Count do
                                            begin
                                               if (Uebersteuern.Daten[q].Personalnummer=Mitarbeiter.Personalnummer) then
                                               begin
                                                 if (Uebersteuern.Daten[q].Datum=SaveDate+tagecounter) and
                                                  (Uebersteuern.Daten[q].SchichtTyp=SaveSchicht) then
                                                    begin
                                                        inc(tagecounter);
                                                        q:=0;
                                                        if tagecounter>4 then break;
                                                    end
                                                end;

                                               inc(q)
                                            end;
                                             if tagecounter>4 then result:=SaveSchicht;
                                          end;

                                      end;
                               end;
                           end;

                    end;

              //##############################Übersteuern Ende##################################


             //sollte der Starttermin vor dem aktuellen datum liegen in der vergangenheit
             if weekly=true then if StartOfAWeek(Year, KW, 1) <StrToDate(Mitarbeiter.Start_Date) then result:='xxx';
             if weekly=false then if Datum <StrToDate(Mitarbeiter.Start_Date) then result:='xxx';

        SchichtList.Free;
end;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf