CPU Auslastung

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

Moderator: Moderatoren

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

CPU Auslastung

Beitrag von Manfred »

Hallo,

mal eine Frage am Rande: Ich habe hier gerade eine Anwendung laufen, die Daten von einer DB in eine andere kopiert und dabei 99% Auslastung erzeugt. Ist das normal? Es werden die Felder ausgelesen und dann in die andere DB geschrieben.
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,

also ich denke mal nicht, denn die Festplatten sind ja viel langsamer als die CPU und der eigentlich limitierende Faktor, was hast du denn für einen Rechner ?
Oder führst du umfangreiche Umrechnungen in For-Next Schleifen mit den Daten durch ?

Nur so als Beispiel:

Mein fast fertiges Testprogramm für die Abfrage meiner Web-Site, fährt 10 Threads gleichzeitig hoch, jeder von denen startet gleichzeitig HTML Anfragen an den Server - über die DSL Leitung raus und wieder rein.

Der abfragende Rechner (Athlon 64 3000+, 1 GB Ram etc, kaum Festplattenarbeit) zeigt zwischen 6 und 10 % CPU Last.

Der abgefragte PC (PIII Celeron 1400 Mhz, 512 MB) mit Apache-Webserver startet PowerBasic-CGI-EXE, diese fordern Daten von der MySQL Datenbank auf dem Server. Ergebnis wird zurückgeliefert. Im Durchschnitt verarbeitet der Web-Server so 4,5 Anfragen pro Sekunde.
Dieser liegt bei der CPU Auslastung zwischen 70 und 85 %.
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,

ich schätze mal, es sind zu umfangreiche Dinge, die ich zwischendurch mache. Ich bin gerade dabei die Routine neu zu programmieren, bzw. nach und nach zu testen, wo die Rechenzeit verloren geht.
Ich wollte nur grob wissen, ob mit diesem "CPU Fraß" zu rechnen ist, oder ob es nicht zum Durchschnitt gehört. Naja, jetzt weiß ich das es wohl nicht normal 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 »

Hallo,

im Betrieb lese ich in einem Programm Textdateien ein, welche durchaus 130 MB groß sein können. Eine Zeile pro Feld. Aus etwa 100 Zeilen wird ein Datensatz. Dabei werden auch Werte umgeformt. Auf meinem PIII 1,266 Mhz Rechner mit 512 MB ist in diesem Falle die Festplatte schnell genug um die Textzeilen zu liefern und 1 DBF append pro 100 Einlesezeilen, lassen den Prozessor auch schwitzen. Evenso reine Auswertungen, in denen ich viele Datensätze linear einlese (da kann die Platte voll schieben) und Berechnungen für Median und Arithmetischen Durchschnitt etc durchführe ...
do ist der Rechner auch um die 60 bis 70 %.
Beides starte ich aber im 2. Thread, sodass der Rechner noch gut bedienbar bleibt.
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,

ich habe hier mal den Codeschnipsel eingestellt, der den Vergleich und die Anpassung vornimmt. Im Moment fällt mir nichts besseres ein, wie ich die Felder prüfen, die Eigenschaften ändern und dann alles wegschreiben könnte.

Code: Alles auswählen

       DO WHILE ! &cDbalt->(EOF())
          &cDbneu->(DBAPPEND())
          FOR nI := 1 TO &cDbneu->(FCOUNT())
              ::nPos := &cDbalt->(FIELDPOS(&cDbneu->(FIELDNAME(nI))))           // Ermittlung der identischen Felder beider DB´s
              IF ::nPos > 0                                                     // identisches Feld wurde gefunden
                 IF &cDbneu->(FIELDTYPE(nI)) = &cDbalt->(FIELDTYPE(::nPos))     // wenn Feldtypen gleich sind
                    &cDbneu->(FIELDPUT(nI,&cDbalt->(FIELDGET(::nPos))))         // Tausch der Feldinhalte
                 ELSE                                                           // andernfalls wird angepaßt
                    IF &cDbneu->(FIELDTYPE(nI)) = "C"                           // es werden zur Zeit nur numerische gegen zeichen und umgekehrt angepaßt.
                       &cDbneu->(FIELDPUT(nI,STR(&cDbalt->(FIELDGET(::nPos)))))
                    ELSEIF &cDbneu->(FIELDTYPE(nI)) = "N"
                       &cDbneu->(FIELDPUT(nI,VAL(&cDbalt->(FIELDGET(::nPos)))))
                    ELSE
                    ENDIF
                 ENDIF
              ENDIF
          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
          &cDbalt->(DBSKIP())
       ENDDO
Vielleicht bin ich ja so umständlich, dass es nur so quietscht? Das System klappt prima, aber die Zeit ist bei einigen 100.000 Sätzen eine Katastrophe und die CPU Auslastung ist am oberen Limit
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
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
nur so eine dumme Idee, aber was passiert denn, wenn Du vor dem Enddo (also vor oder nach dem Skip) ein Sleep(10) einbaust? Ich meine natürlich bezogen auf die Auslastung - das es etwas länger läuft, ist mir schon klar... :wink:
Würde mich einfach mal interessieren...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
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 Martin,

werde ich nachher mal ausprobieren. Ich habe nur im Moment von 600.000 Sätzen 180.000 weg und würde die gerne weiter durchlaufen lassen. Es dauert sonst nochmal so schweinelange.

Ich gebe nachher bekannt, ob und was es bringt...
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 »

DO WHILE ! &cDbalt->(EOF())
&cDbneu->(DBAPPEND())
FOR nI := 1 TO &cDbneu->(FCOUNT())
::nPos := &cDbalt->(FIELDPOS(&cDbneu->(FIELDNAME(nI)))) // Ermittlung der identischen Felder beider DB´s
IF ::nPos > 0
du frägst hier in jedem Satz die Anzahl der Felder und die Feldpositionen mit Namen ab, um die Verarbeitungsart zu ermitteln. Alle diese Infos stehen (falls die DBE das nicht zwischenspeichert) im DBF Header, die Daten sind irgendwo weiter unten (Festplatte muß dauernd springen, wenn Dateigröße größer als Plattencache). Diese Infos muss man nur einmal ermitteln, denn sie gelten für jeden Datensatz gleich.
Außerdem verwendest du Makros für den Alias, die aufgelöst werden müssen. Das kostet unnötige Zeit, was bei 1000 Datensätzen kaum auffällt, summiert sich dann aber nach oben ...

In Kürze würde ich

1. Sicherstellen, dass der Programmteil und damit die DBFs exclusiv geöffnet werden können
-> dramatisch schnellere Dateioperationen !
2. dann kann man 'lokale Alias' verwenden:

Code: Alles auswählen

use (cDateinameAlt) alias MyALT NEW EXCLUSIVE
use (cDateinameNeu) alias MyNeu NEW EXCLUSIVE
... MyAlt-> ... MyNeu->   dürfte deutlich schneller sein !
wenn das nicht geht, dann (exclusive oder zumindest mit FLOCK)
local nAliasAlt,bAliasNeu
use (cDateinameAlt)  NEW // kein Alias
if neterr() 
   Abbruch ...
endif
nAliasAlt := select()
use (cDateinameNeu)  NEW // kein Alias
if neterr() 
   Abbruch ...
endif
nAliasNeu := select()... 
(nAliasAlt)-> ... (bAliasNeu)->   dürfte deutlich schneller sein !
Merke: Zeichenkettenoperationen dauern länger als Numerische, Macros dauern am längsten.
3. Alles einmalige direkt ermitteln und in LOCAL Vars speichern

Code: Alles auswählen

  nFcountAlt := MyAlt->(fcount())
nFcountNeu := MyNeu->(fcount())
etc.
4. In einem Array die Infos sammeln die wir zum umkopieren brauchen, hier könntest du deine Schleife für einen Datensatz verwenden.
das Array könnte dann so aussehen:

{ {nAltFeld,nNeuFeld,nVerarbeitungsart },
für jedes Feld der NEUEN Datei eine Zeile }

Code: Alles auswählen

z.B. 
#define KOPIEREDIREKT          1
#define UMWANDELNSTR2NUM  2
#define UMWANDELNNUM2STR  3
#define ALTFELD 1 // nur für Fielput und Fieldget
#define NEUFELD 2

aKopiere := { { 1,1,KOPIEREDIREKT},;  // erstes Feld braucht keine Umwandlung, Position ist gleich.
   {2,3,UMWANDELNSTR2NUM},; // altes Feld 2 wird mit VAL() zu Feld 3 ...
   {5,2UMWANDELNNUM2STR},; // altes Feld 5 wird mit STR() zu Feld 2
   etc.

im Programm, dann

do while ! MyAlt->(eof())
    MyNeu->(dbappend())
    for x := 1 to nFcountNeu
         do case
              case aKopiere[x,3] = KOPIEREDIREKT
                     MyNeu->(fieldPut(aKopiere[x,NEUFELD], ;
                                    MyAlt->(fieldGet(aKopiere[x,ALTFELD]))))
              case aKopiere[x,3] = UMWANDELNSTR2NUM
                     MyNeu->(fieldPut(aKopiere[x,NEUFELD], ;
                             VAL( MyAlt->(fieldGet(aKopiere[x,ALTFELD])))))
              case aKopiere[x,3] = UMWANDELNNUM2STR
                     MyNeu->(fieldPut(aKopiere[x,NEUFELD], ;
                             str(MyAlt->(fieldGet(aKopiere[x,ALTFELD])))))
         endcase
....
oder du legst gleich im Array den passenden codeblock ab, den du für das Feld im Programm ermittelt hast:

Code: Alles auswählen

local cArbeit, bArbeit 
....
* Ermittle die Feldzusammenhänge - nur in einem Datensatz !
aKopiere := {}
for x := 1 to nFcountNeu
     do case
         case ... beide Felder sind vom gleichen Typ
                cArbeit := "{|| MyNeu->"+Fieldname(x)+" := MyAlt->"+Fieldname(x)+"}"
                bArbeit := &(cArbeit)
         case ... von STR nach NUM
                cArbeit := "{|| MyNeu->"+Fieldname(x)+" := val(MyAlt->"+Fieldname(x)+")}"
                bArbeit := &(cArbeit)
         case ... von NUM nach STR
                cArbeit := "{|| MyNeu->"+Fieldname(x)+" := str(MyAlt->"+Fieldname(x)+")}"
                bArbeit := &(cArbeit)
     endcase
     aadd(aKopiere , bArbeit)  
...

dass hier in beiden Fällen der Feldname des neuen Feldes verwendet wird, ist kein Problem, solange beide Dateien den gleichen Feldnamen haben, sonst muss das anders geschrieben werden.

So nun hast du ein Array mit der Kopieranweisung für jedes Feld in einem compilierten Codeblock, jetzt die Schleife:

do while ! MyAlt->(eof())
    MyNeu->(dbappend())
    for x := 1 to nFcountNeu
         eval(aKopiere[x])
    next
   ...
Der zweite Ansatz ist flexibler, da man hier die VAL und STR Befehle je Feld genau festlegen kann, was im oberen Beispiel eher schwierig ist.
Beim Basteln des Codeblock soll man LOCAL Variablen nutzen, man muss nur darauf achten, dass diese vor der Compilierung in reinen Text aufgelöst werden. Der Zwischenschritt, erst cArbeit füllen und danach bArbeit bilden, erleichtert die Fehlersuche gewaltig.

Wichtig ist immer, den Schleifenanteil der alle Datensätze durchlaufen muss von allem Ballast zu befreien. Auch wenn die Operation nur sehr wenig Zeit kostet, bei 100000 Datensätzen wird man es merken.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hubert,
clever :!: :thumbright:

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
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 »

@martin

ich habe das Sleep(10) direkt nach dem Skip eingebaut. Wie Du schon meinstest, die Dauer erhöht sich ca. um den Faktor was weiß ich was ;-)

Die CPU Auslastung geht aber gen 0

@Hubert,

ich werde mich jetzt daran machen und Deinen Vorschlag umsetzen. Der 1.Durchlauf mit meiner Lösung dauerte mindestens 2,5 Stunden. Jetzt bin ich mal gespannt, wie es mit Deiner Lösung aussieht..
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
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
vielen Dank für das Testen. Das Ergebnis hatte ich vermutet, da Du Windows zwischendurch Zeit läßt, auch mal andere Dinge zu tun.
Dieses Sleep() brauchst Du nicht bei jedem Skip machen, sondern analog beim Ausgeben Deines Zählers.
Alternativ/Zusätzlich kannst Du auch mit dem Parameter für Sleep() experimentieren.
Mit Huberts Tipps wirst Du auf jeden Fall die Laufzeit minimieren können. Die CPU-Auslastung sollte aber eigentlich trotzdem weiterhin recht hoch bleiben (würde ich denken).

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
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,

der erste Schritt war, neben dem exclusiven Öffnen der Zieldatenbank (die war die ganze Zeit schon exclusive), die Quelldatenbank auch exclusive zu öffnen. Das brachte keinen Erfolg. Zumindest konnte man innerhalb der ersten 2000 Sätze keinen Tempogewinn sehen.

Jetzt mache ich den nächsten Schritt.
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 »

Immer eins nach dem anderen (und Punkte sammeln ;-) )

Hi Hubert,

Jetzt habe ich die Makros gegen locale Variablen ausgetauscht, so wie Du vorgeschlagen hast. Auch hier innerhalb der ersten 3000 Sätze kein Unterschied zu bemerken. Aber trotzdem schonmal Danke für den Tipp. Irgendwie habe ich da noch eine Schere im Kopf. Das ich da nicht selbst drauf gekommen bin.

Schritt 3.....
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 »

neben dem exclusiven Öffnen der Zieldatenbank (die war die ganze Zeit schon exclusive), die Quelldatenbank auch exclusive zu öffnen. Das brachte keinen Erfolg
Beim Lesen spielt es keine Rolle ob exclusiv oder nicht, da die Festplatte im cache viele Datensätze vorhält (bei sequenzillem Zugriff ohne Index).

Beim Schreiben werden mehrere Sätze von der DBE gepuffert um dann größere Blocks wegzuspeichern.

Ich bin wirklich gespannt was es insgesamt ausmacht, aber bei 3000 Datensätzen wird man es schon mit seconds() prüfen müssen :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 »

Hi Hubert,

ist mir schon klar. Ich habe jetzt die einzelnen Versionen getrennt benannt und werde dann später mal einen längeren Durchlauf machen.

Bis jetzt habe ich nur eine Stoppuhr nebenher laufen lassen:

Zwischenstand:

Lokale Variablen und von String auf numerisch umgestellt beim Select. Bisher noch kein Unterschied bei 3000 Sätzen.

Im Endeffekt geht es ja nur darum, was passiert, wenn alles umgebaut wurde...

Das werden wir gleich wissen. :-)
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 »

Manfred hat geschrieben:Bis jetzt habe ich nur eine Stoppuhr nebenher laufen lassen:

ich nehme immer die Stoppuhr von Xbase++

Code: Alles auswählen

local nStart
nStart := seconds()
....
? "Dauer:",seconds()-nStart,"Sekunden"
Gruß
Hubert
MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Hallo Manfred,

ich habe bei mir mal ein Gegenstück gesucht. Datenbank ca. 600.000 Sätze, bei mir mit 65 Feldern, Typ von allem etwas, macht ein knappes Giga. Sowas umzurödeln muss schon einen Grund haben. Wäre es nicht besser Erfassung und Verarbeitung der Daten zu ändern um sie entsprechend handeln zu können?

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 »

Hi Mabela

ich kann Dir im Moment gedanklich nicht folgen..... :-(

Hilf mir bitte auf die Sprünge....
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 »

Ich vermisse Manfreds Funktion immer, wenn ich mal wieder in DBU vergessen habe, dass ein Typwechsel in der dbf Struktur keine Daten umwandelt, sondern per Fehlermeldung abbricht.
Gruß
Hubert
MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Vielleicht muss mir auf die Sprünge geholfen werden. Du hast Daten in einer DB z.B. als String, die in der neuen DB als Value und umgekehrt gebraucht werden. Da Dir der Zeitfaktor wichtig war, meinte ich, dieser Vorgang der Umwandlung muss immer wieder (täglich oder so) erfolgen.
Für eine mehr oder weniger einmalige Umwandlung nehm' ich alles zurück und behaupte das Gegenteil.

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 »

Es geht darum generell eine DB Anpassung zu erzeugen, wenn sich die Struktur geändert haben sollte. Das kann 1x am Tag, das kann aber auch 1x im Jahr passieren, je nachdem, wie schnell die Entwicklung und die Erfordernisse voranschreiten. Wobei 1x am Tag nicht die Regel ist. Allerdings in der Entwicklungsphase kann es sogar mehrmals am Tag passieren.

Ansonsten wüßte ich auch nicht, wie man die Sache automatisieren sollte.
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 »

Bei "heißen" Daten mache ich das, wenn der Umfang der zu ändernden Felder nicht zu groß ist, in der DB (SI-Kopie), exclusive braucht man sowieso, man kann nach dem Durchlauf Korrektur lesen (lass immer ein paar Indizes mitlaufen, die Ausreißer stehen meist am Anfang und Ende), bei Fehlern sieht man in einer DB gleich wo es hakt. Etwas umständlicher ist es natürlich wenn die Feldnamen die alten bleiben müssen, das hat der Vorteil der Korrektur aber meist aufgewogen.

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 »

:shock:

vielleicht bin ich ja im Moment mit meinem Gehirnschmalz woanders, aber ich verstehe nur Bahnhof......

Sorry
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 »

Was die CPU Auslastung angeht, muß ich mich etwas korrigieren.
sowohl der DBEXPORT einer DBF als auch meine umfangreichen Rechenroutinen bringen die Athlon 64 3000+ an die 100% Systemlast heran. Wenn man diese in einen eigenen Thread auslagert (ist nicht schwer) spielt das für das eigenen Programm aber keine große Rolle. Wenn nicht muss man ab und zu sehr kurz (max 0.01) die Eventloop aufrufen:

Code: Alles auswählen


im Mainprogramm:

DoEventLoop()   // ohne Zeitvorgabe, bis CLOSE ...

in Schleifen z.b. für 0,5 Sekunden

DoEventLoop(0.5)
DoEventLoop(0.001)  // oder 10/1000 Sekunden 

*-----------------------------------------------------------------------------
FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1:=nil, mp2:=nil, oXbp:=nil

   DEFAULT nSeconds to 0                     // Standard ist endlose Ausführung

   nBisSeconds := seconds() + nSeconds

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
            * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_F1
                       * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
                       MsgBox("Die Hilfe ist für dieses Programm noch nicht erstellt.")
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0 .and. nBisSeconds < seconds() // nur wenn keine endlose Ausführung
         exit
      endif
   ENDDO
return nil
Gruß
Hubert
MaBeLa
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 21
Registriert: Mi, 08. Mär 2006 14:08
Wohnort: bei Berlin

Beitrag von MaBeLa »

Manfred hat geschrieben::shock:

vielleicht bin ich ja im Moment mit meinem Gehirnschmalz woanders, aber ich verstehe nur Bahnhof......

Sorry
... dann nehm ich mal den nächsten Zug.

Tschüß
MaBeLa
Antworten