CPU Auslastung

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Ich hab's mal probiert, aber vielleicht bin ich ja im falschen Zug.

Ausgangbasis: DB 598.877 Sätze, 65 Felder, 800MB

Annahme: 5 Felder ändern sich

ich kopiere die Struktur(alt) und erweitere sie um 5 neue Felder

nehme meine Standardanwendung und füge die fünf Zeilen für die neuen Felder ein ( Feldalt-String in FeldneuValue etc.)

(ziehe darin die Datenbank in Strukturneu, append ca. 1 min)

lasse die Anwendung laufen ( 2 min 21 sec auf dem Netzlaufwerk)

schmeiße die alten Felder raus, benenne neue um, je nachdem

fertig, insgesamt max. 15 min

Sicher, kein großes Kino...

Gruß MaBeLa
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Wenn man es schafft, die internen Befehle append from ... bzw. replace all .... for ... zu benutzen sind die Datenbankoperationen wesentlich schneller als mit do while ... skip .

Aber wie machst du einen append wenn der Feldname gleich sein soll der Typ aber von c 5 auf n 5 gewechselt hat ? Ich muss da immer ein Pseudofeld einfügen und mehrfach appenden.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi,

mir stehen die Haare zu Berge....

Code: Alles auswählen

       FOR nI := 1 TO nFcountNeu
           ::nPos := (nDbalt)->(FIELDPOS((nDbneu)->(FIELDNAME(nI))))            // Ermittlung der identischen Felder beider DBs
           IF ::nPos > 0                                                        // identisches Feld wurde gefunden
              IF (nDbneu)->(FIELDTYPE(nI)) == (nDbalt)->(FIELDTYPE(::nPos))     // wenn Feldtypen gleich sind
                 cArbeit := "{|| (nDbneu)->"+FIELDNAME(nI)+" := (nDbalt)->"+FIELDNAME(::nPos)+"}"
                 bArbeit := &(cArbeit)
              ELSE
                 IF (nDbneu)->(FIELDTYPE(nI)) == "C" .AND. (nDbalt)->(FIELDTYPE(::nPos)) == "N"
                    cArbeit := "{|| (nDbneu)->"+FIELDNAME(nI)+" := VAL((nDbalt)->"+FIELDNAME(::nPos)+")}"
                    bArbeit := &(cArbeit)
                 ELSEIF (nDbneu)->(FIELDTYPE(nI)) == "N" .AND. (nDbalt)->(FIELDTYPE(::nPos)) == "C"
                    cArbeit := "{|| (nDbneu)->"+FIELDNAME(nI)+" := STR((nDbalt)->"+FIELDNAME(::nPos)+")}"
                    bArbeit := &(cArbeit)
                 ENDIF
              ENDIF
              AADD(aKopiere, bArbeit)                                           // ins Array schreiben, was damit gemacht werden soll
           ENDIF
       NEXT
       DO WHILE ! (nDbalt)->(EOF())
          (nDbneu)->(DBAPPEND())
          FOR nI := 1 TO nFcountNeu
              EVAL(aKopiere[nI])
          NEXT
          IF ++nZaehler % 200 = 0                                               // jeder einzelne Satz würde wohl bei großen DB zu viel Zeit kosten
             oStatic8:SetCaption(RIGHT("00000" + STR(nZaehler),6))              // Anzeige, welcher Satz gerade abgearbeitet wird
          ENDIF
          (nDbalt)->(DBSKIP())
       ENDDO
 
es ist der Wurm drin. Habe ich hier einen Tippfehler?
Es werden die exakten Zahlen und Feldnamen über den Debugger angezeigt, aber sobald der Codeblock erzeugt und in cArbeit geschrieben wird, werden die Felder um 1 verschoben. D.h. es stehen die richtigen Zahlen - nI ::nPos - drin, aber es wird immer ein Feld weiter genommen aus nDbneu, als nI anzeigt.

Wenn ich dann bei eval() ankomme, behauptet das Programm eine unbekannte Variable "ndbneu" zu haben. Ich verstehe nichts mehr.
Ich habe im Debugger nachgesehen und ausprobiert, nDbneu und nDbalt haben die richtige Bereichsnummer stehen.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Ich nehme die leere Ausgangsstruktur ( c 5 enthalten) und hänge das neue Feld n 5 an. Mache dann ein append in die leere "neue" Struktur. Man kann aber natürlich auch gleich mit Datensätzen die Struktur ändern, natürlich nur auf einer Sicherheitskopie. Das ist mehr eine Sache der Performance, wie groß ist die DB, wo liegt sie, wie schnell ist mein Netz.
Dann ändere ich meine Anwendung, ich mache auch nur ein Do ... While ... skip und schreibe val(c 5) in n 5, lege vorher ein paar Indizes im PRG an, wenn nötig ( siehe heut' vormittag), und lass es laufen. Inhalt n 5 ist jetzt val(c 5) und ich schmeisse c5 raus. Manchmal behalte ich c5 auch noch für den Übergang.
Beispiel: eine rein numerische Artikelnummer bekommt Buchstaben dazu, in Browseobjekten ist es im Übergang für den Nutzer manchmal ganz nützlich zu sehen ob er richtig liegt mit der neuen Nummer.

Gruß MaBeLa
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Das sieht auf den ersten Blick so aus, als wenn Du nur 1 DB hast, oder aber für jede DB eine eigene Anpassung schreiben müßtest, oder hast?
Meine Methode kann ALLE DB im System anpassen, egal wieviel Felder, egal wie goß. Im Moment allerdings nur Char zu numerisch und umgekehrt, oder eben halt direkt übernehmen, wenn sich Feldtype nicht geändert hat.

Klär mich auf, wenn ich falsch liege.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2936
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von Wolfgang Ciriack »

Warum nehmt ihr nicht die Funktion DbImport(), da kann man eine Felderliste angeben. Bei Wechsel von C nach N oder umgekehrt könnte man das Feld erst einmal weglassen und in einem separatem Durchlauf ersetzen. Wie sich das geschwindigkeitsmäßig auswirkt kann ich allerdings nicht sagen.
Viele Grüße
Wolfgang
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hallo Wolfgang

das System als solches läuft ja eigentlich prima. Es dauert halt nur eine ganze Zeit. Der Vorschlag von Hubert war ja auch i.O., soweit ich das beurteilen kann, aber irgendwo habe ich einen Fehler drin, oder er.... :-( Leider habe ich noch keine wirkliche Ahnung von Codeblöcken und finde diese Macke nicht.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Das ist richtig, ich muss in meiner Anwendung für jede Datenbank pro Feldänderung eine Zeile ändern. Das ging bis jetzt immer gut. Ich habe in verschiedenen Datenbanken immer gleiche Feldnamen bei gleichem Inhalt, so daß sich auch bei systemweiten Änderungen der Aufwand in Grenzen hält. Sicher könnte man hier noch Automatismen einbauen, aber das Ändern des Quellcodes ging immer so schnell, daß ich zum Erweitern, ich gestehe, immer zu faul war.

Gruß MaBeLa
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

@manfred

mach mal nach jeder Zuweisung von cArbeit ein

? cArbeit

die Feldnamen müssen gleich sein.
Ich sehe es mir zu Hause an, jetzt muss ich auf die Bahn.
Und ich gebe heute Abend keine Ruhe, bis es funktioniert - jetzt will ich es wissen :wink:
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

@Hubert,

ich habe es im Debugger nur angesehen und da war schon der Futtsack
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Das macht Probleme, sobald in der neuen DB ein Feld auftaucht, welches in der alten nicht drin ist.
Es fängt damit an, dass das 1.Feld gleich ein neues Feld ist.
Wenn ich in der Blockzuweisung direkt nI um 1 abziehe, dann paßt es genau so lange, bis wieder ein Feld kommt welches in der neuen, aber nicht in der alten DB ist. Ab da wird wieder um 1 versetzt übernommen. Wenn ich aber zum Zeitpunkt des Übernehmens in cArbeit über das Kommando Fenster mir aufrufe, welches Feld angesprochen wird, dann wird das korrekte zurückgegeben. tsetsetse
Tja, jetzt heißt es nachsehen, warum der Fehler passiert. :?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Es gibt noch was merkwürdiges.

Irgendwann taucht ein falscher Feldname auf. ich habe noch nicht herausgefunden, woher der mittendrin kommt.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

ich habe folgende Probleme ausgemacht - und im Anschluß an diese eMail kommt dann meine funktionierende Lösung, welche du in deine Klasse einbauen kannst:

Code: Alles auswählen

           cArbeit := "{|| (nDbneu)->"+FIELDNAME(nI)+" := STR((nDbalt)->"+FIELDNAME(npos)+")}"
                    bArbeit := &(cArbeit)
                 else     //********* der ELSE Zweig wird für neue Felder benötigt.
                    cArbeit := "" // Kennzeichnet neues Feld -> keine Arbeit
                 ENDIF  
              ENDIF
              if ! empty(cArbeit)      // NUR wenn Arbeit vorliegt, sonst doppelter Eintrag 
                  AADD(aKopiere, bArbeit)                                           // ins Array schreiben, was damit gemacht werden soll
              endif
           ENDIF
----------

"{|| (nDbneu)->"+FIELDNAME(nI)+"...FIELDNAME(npos)

dies funktioniert nur wenn nDbneu eine Private oder Public ist,
bei Classen / Win32 Programmierung muß man diese meiden ...

FIELDNAME(nI)+"...FIELDNAME(npos)

per Definition der Aufgabe sind beide identisch und schwer zu debuggen !

 DO WHILE ! (nDbalt)->(EOF())
          (nDbneu)->(DBAPPEND())
          FOR nI := 1 TO nFcountNeu  ///  wir wollen hier NICHT alle Felder 
              EVAL(aKopiere[nI])         // durchlaufen, sondern alle AUFTRÄGE
          NEXT 

Ich habe den Code angepasst und er läuft, allerdings in meiner Schreibweise ... viele Variablen, wenige Funktionen - ist leichter im debugging und kostet nichts mehr.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hm, ich habe den Aliasnamen benutzt...
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Dieses Beispielprogramm legt eine kleine DBF (1000000) Datensätze mit etwa 32MB an. Anlegen dauert auf meinem Rechner etwa 45 Sekunden.
Falls die Datei vorhanden ist, geht es gleich weiter ... Taste drücken

Danach wird umkopiert 1000000 in neue Datei 42 Sekunden.
Es werden zwar nur 5 Felder umkopiert, aber bei 50 Feldern sollte es die 600 Sekunden nicht übersteigen.

Code: Alles auswählen

#pragma library( "XBTBASE1.LIB" )
#pragma library( "XBTBASE2.LIB" )


procedure main
   local aAltStru := { {"TEST"  ,"C",10,0},;
                       {"Alter" ,"C", 3,0},;
                       {"PLZ"   ,"N", 5,0},;
                       {"Datum" ,"C",10,0},;
                       {"Ort"   ,"C",10,0} }
   local aNeuStru := { {"Name"  ,"C",10,0},;
                       {"Datum" ,"D", 8,0},;
                       {"Alter" ,"N", 3,0},;
                       {"PLZ"   ,"C", 5,0},;
                       {"Ort"   ,"C",10,0} }
   local nAlt,nNeu,x
   ? "TEST3"
   if ! file("AltDat.DBF")
      dbcreate("AltDat",aAltStru)
   endif
   if ! file("NeuDat.DBF")
      dbcreate("NeuDat",aNeuStru)
   endif

   use AltDat exclusive
   nAlt := select()

   if lastrec() < 1000000
      ? "Alte Datei f
Zuletzt geändert von brandelh am Di, 28. Mär 2006 10:07, insgesamt 3-mal geändert.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hm, ich habe den Aliasnamen benutzt...
der Aliasname darf nie in Klammern, Klammern nimmt man nur bei local Vars oder Funktionen.

Außerdem hast du ::nPos verwendet, daher vermute ich dass dies in einer Methode deiner Datenbankklasse verwendet wird. Wenn du hier einen Alias vorgibst, muß dass bei der 2. Instanz schief gehen. Daher verwende ich immer

Code: Alles auswählen

use dateiname NEW
if ! neterr()
   ::nAlias := select()
das geht immer.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Es sieht jetzt ganz anders aus im Codeblock, aber trotzdem habe ich immer noch den Feldversprung, wenn das 1.Feld aus der neuen DB nicht in der alten DB ist.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Mit meinem Code ?

meinen Code genau mit deinem verglichen ?
Am beste komplett ersetzten.

Ein Codeblock muß in etwa so aussehen:

Code: Alles auswählen

{  
  { || (   1)->VorName := (  2)->VorName },;          // gleicher Feldtyp 
  { || (   1)->PLZ := str((  2)->PLZ ) },;    // C -> N
  { || (   1)->KuNr := val((  2)->KuNR) },;    // N -> C
}
wobei die ( 1) abhängig von der tatsächlichen Workarea sind !
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Trörö

es klappt.

Von > 2.5 Stunden auf knapp 7 Minuten Dauer runtergeschraubt.

Allerdings hatte die Sache noch einen kleinen Fehler, in den ich natürlich prompt reingerannt bin. Wenn die Felder vom Typ her gleich sind, da hast Du FIELDNAME(nI) und FIELDNAME(nPOS) stehen. Das ist mir dann irgendwann auch aufgefallen.

Ansonsten kann ich mich hier nur bis zur Unkenntlichkeit bei Dir bedanken Hubert.

Wer weiß, was ich noch für einen Mist programmiert habe, der nur bremst. Auf jeden Fall wäre ich auf Deine Lösung mit meinem Wissenstand nieeee gekommen. Woher weiß man sowas?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

hier noch ein Ergebnis mit meiner Monsterdatei auch auf 1000000 Datensätze aufgeblasen:

Lastrec(): 1.000.000
Anzahl Felder: 113
Satzlänge: 1572 Zeichen
Dateigröße: 1.565 MByte

In der neuen Datei ist das 1. Feld und das letzte Feld ganz neu,
etwa 6 Umwandlungen (alle Arten).

Der Umwandlungslauf dauert 12 Minuten.

In meinem Code habe ich die Zeile mit dem FIELDNAME Ballast korrigiert und unter LOCAL auch noch cArbeit eingetragen. Bei meinem ersten Beispiel war es kein Problem, aber bei meiner großen bin ich auch schon auf den Fehler gestoßen.

PS: Ich kann nur raten, den Quellcode so einfach wie möglich zu halten.

Wenn ich meinen 15 Jahre alten Quellcode ansehe, fallen mir ab und zu Stellen auf, bei denen ich denke 'oh je so schlecht' und in dem vor 10 Jahren dann 'oh je so genial, was hatte ich mir nur dabei gedacht' :?:
Die erste Variante sehe ich heute lieber, die zweite bringt wirklich Kopfzerbrechen.
Zuletzt geändert von brandelh am Di, 28. Mär 2006 0:43, insgesamt 1-mal geändert.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

> Woher weiß man sowas?

19 Jahre Erfahrung. Zuerst mit langsamen Rechnern, dann mit immer größeren Dateien. UND VIELEN EIGENEN FEHLERN !
Und in Foren nachfragen ...

Eine Schleife mit 1000 Durchläufen kann man machen wie man will, wenn es aber 10 oder 100 mal mehr sind, muß man in dieser Schleife alles bis auf das nötigste reduzieren. Festplattenzugriffe und Bildschirmausgaben sind langsam also Vorsicht damit.

Das gilt übrigens auch für die Eventloop. Manche hauen da richtig code rein, das ist aber nicht sinnvoll.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Jetzt noch kurz ein paar Ergebnisse zur CPU Auslastung:

Code wie oben 100 % für 12 Minuten etwa 1000 pro Sekunde
@21,10 say "bis jetzt:"+str(seconds()-nStart)+" Sekunden"
sleep(10)

-> optisch eine deutliche Verlangsamung, CPU Last 65-70%
-> meine im Programm hinterlegte Hochrechnung kommt auf 1790 Sekunden, das wäre mehr als das doppelte wie die idealen 712 Sekunden. Eindeutig keine gute Idee.

@21,10 say "bis jetzt:"+str(seconds()-nStart)+" Sekunden"
sleep(1)

-> etwas langsamer, 90% CPU Last, gleichzeitig diesen Artikel tippen ist gut möglich.... 12 Minuten und 50 Sekunden !
Gar nicht so viel.

Wie gesagt, Athlon 64 3000+, 1 GB Ram (512 wären auch genug), IBM Festplatte mit 120 GB - DMA5 oder 6, also recht modern.

sleep(1) kann helfen das Multitasking zu verbessern, bremst aber den Rechner nur unnötig aus, wenn sonst nichts zu tun ist.
Besser eigene THREADS für solche Aufgaben nutzen.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Moin Hubert,

war ja gestern (heute morgen) wohl ne Powershow?

Nochmals 1000 Dank für Deine Bemühungen.
Die CPU Auslastung habe ich jetzt nicht mehr geprüft, aber sie steht nach dieser drastischen Zeitersparnis nicht mehr zur Debatte. Bei Gelegenheit werde ich aber trotzdem nachsehen.

Tja, im Moment fehlen mir einfach die Worte, wenn ich mir anschaue, welche Zeitfresser es gibt, bzw. wie unproduktiv programmiert werden kann, wenn man nicht aufpaßt. Das hätte ich so nicht erwartet.

PS: Bevor ich es vergesse: Ich habe die einzelnen Stufen durchgetestet. Einen echten Tempogewinn hat die Sache mit der Makroentfernerei gebracht. Also das kostet wirklich Zeit. Alles andere war nicht wirklich merkbar. Der spätere Ablauf ist dann so wie Du auch beschrieben hast: >1000 Sätze /Sekunde.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hi,
das Beipiel ließe sich noch weiter optimieren, wenn die Prüfung auf Basis von Datei-Struktur-Arrays erfolgt (DbStruct() ). Da in diesen Arrays alle Informationen für ein Dateiabgleich und für den Export enthalten sind, braucht man weniger (zeitintensive) Dateizugriffe und es müssem auch weniger Makros evaluiert werden, da zur Prüfung die Informationen im Hauptspeicher allein abgearbeitet werden können.

Gruß, Olaf
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21198
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Der Strukturvergleich findet doch nur 1x statt, am Anfang. Der Rest ist doch das zeitintensive: Datentausch und anhängen...
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Antworten