bytes in dim feld lesen zu langsam

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

x_to

Betreff: bytes in dim feld lesen zu langsam

BeitragSo, Nov 22, 2009 22:21
Antworten mit Zitat
Benutzer-Profile anzeigen
daß arrays für große files nicht angebracht sind ist bekannt, aber 1 MB ist für mich nicht viel, aber mit diesem code kann man einschlafen:

Code: [AUSKLAPPEN]
Dim bytes(FileSize(datafile$))
For i = 1 To FileSize(datafile$)
   bytes(i)=ReadByte(datafilehandle)
   UpdateProgBar statusprogbar,i/FileSize(datafile$)
Next


für 1 MB brauche ich locker bald 5 (!) minuten....
geht das auch irgendwie schneller ?
mit banks will ich bewußt nicht arbeiten....Sad

Goodjee

BeitragSo, Nov 22, 2009 22:24
Antworten mit Zitat
Benutzer-Profile anzeigen
versuchs mit strings, sind ja eg auch nur aneinandergereite bytes.

aber die vernünftigste lösung währen eg banks
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Holzchopf

Meisterpacker

BeitragSo, Nov 22, 2009 22:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde FileSize vorgängig in einer Variablen speichern und dann damit arbeiten, anstatt bei jedem Schleifendurchgang (auch durch die Abbruchbedingung), die Funktion aufzurufen. Ausserdem wär's noch interessant, zu wissen, wie schnell die Schleife denn so arbeitet, wenn du "UpdateProgBar" auskommentierst.
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

x_to

BeitragSo, Nov 22, 2009 22:47
Antworten mit Zitat
Benutzer-Profile anzeigen
mit strings gehts 4mal so schnell...is ja klar...ich muß nur die einzelnen bytes dann noch ausmaskieren.
"updateprogbar" zu entfernen bringt nicht viel...würde für mich auch wenig sinn machen.
aber die filesize in eine einzelne variable zu speichern hat auch was gebracht...

Eingeproggt

BeitragSo, Nov 22, 2009 23:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab auch das Gefühl dass dein "UpdateProgBar" schuld ist - wäre es eine Lösung, dies Funktion sagen wir nur alle 100 Byte aufzurufen? Also n Zähler mitlaufen lassen, wenn Zähler=100 dann UpdateProgBar und Zähler wieder zurücksetzen.

EDIT: Noch n gaaaaanz böser Verdacht... Zeichnest du deine "ProgBar" vielleicht mit Flip 1? Weil dann würde jedesmal n paar Millisekunden gewartet werden, 1Million mal n paar Millisekunden - das machts aus! Also Flip 0 wäre da auf jeden Fall zu empfehlen und eben auch dass man den Fortschrittsbalken nicht bei jedem Byte neu zeichnet. (Ich nehm einfach mal an das geschieht in der Funktion).

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Midimaster

BeitragMo, Nov 23, 2009 3:34
Antworten mit Zitat
Benutzer-Profile anzeigen
ich denke auch, die UpdateProgBar so oft aufzurufen, kostet imens Zeit. Bringt auch nichts, sie so oft zeichnen zu lassen, da bewegt sich bestimmt nichts am Bildschirm nach den Einzelnen Bytes. Möglicherweise reicht sogar alle 1000 oder 10000 Bytes. Bei 1MB wären das ja immer noch 100 sichtbare Schritte. Und sollte in der UpdateProgBar tatsächlich ein FLIP 1 stecken, würde das Laden immer noch (nur wegen des FLIP 1) mind. 1.6 sek dauern.

Code: [AUSKLAPPEN]

Global i%,j%,zeit%
Global AnzahlBytes%=FileSize(datafile$)
Dim bytes(AnzahlBytes)
For i = 1 To AnzahlBytes Step 10000
   zeit=Millisecs()
   for j=i to i+10000
      if j>AnzahlBytes then Exit
      bytes(j)=ReadByte(datafilehandle)
   Next
   Zeit=Millisecs()-zeit
   debuglog Zeit
   UpdateProgBar statusprogbar,i/AnzahlBytes
Next


Teste das Laden mal wirklich ohne UpdateProgBar und stopp die Zeit. Würde mich nciht wundern, wenn es so schnell geht, dass eine Progressbar gar keinen Sinn mehr macht.

BladeRunner

Moderator

BeitragMo, Nov 23, 2009 6:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Mein Vorgehen wäre:
- Auslesen der Dateigrösse mittels Filesize
- Aufteilen in 100 Pakete
- eine angelegte Bank mit readbytes befüllen.
- Progressbar um eines erhöhen

Es gibt in deinem Code zwei Bremsen:
Updateprogressbar sowie readbyte. Da Du byte für byte einliesst wird dein Programm sehr langsam. Daher solltest Du readbytes bevorzugen.

Es kann sich je nach Filegrösse sogar lohnen das File nur in einige wenige Pakete zu zerlegen - die Progressbar muss ja nicht prozentweise steigen, und es ist sinnvoll viele Leseoperationen zusammenzufassen.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

x_to

BeitragMi, Nov 25, 2009 23:48
Antworten mit Zitat
Benutzer-Profile anzeigen
danke für eure tips, aber ich habe jetzt das nächste problem:

ich habe die progbar global eingerichtet und die schleife in eine function gepackt, allerdings funktioniert der
"Updateprogbar" befehl nicht innerhalb der function...

ist das normal ???

ich nutze BlitzPlus 1.47

BladeRunner

Moderator

BeitragMi, Nov 25, 2009 23:57
Antworten mit Zitat
Benutzer-Profile anzeigen
ohne code ... nix los...
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

BBPro2

BeitragDo, Nov 26, 2009 0:44
Antworten mit Zitat
Benutzer-Profile anzeigen
normal ist es natürlich nicht,
wird ein programmierfehler sein.. aber wie gesagt - ohne code kann man dir nicht helfen

ozzi789

BeitragDo, Nov 26, 2009 9:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Wahrscheinlich bekommst du "Invalid ProgBar Gadget handle", das liegt daran, das du updatebar auf einen Progbar anwendest, den du im Hauptprogramm erstellt hast.
Das ist das selbe bei Variablen, in einer Function sind alle Variabeln nicht verfügbar, da function ein eigenständiges Unterprogramm ist.

Dies merkst du wenn du in der Function eine Variable erstellst oder änderst, und es im Hauptprogramm ausgibst, nichts gscheides rauskommt

Lösung:
Entweder du deklarierst den Progbar und die Variablen Global (so werden sie für das ganze Programm lesbar) oder du löst es so, mit "Parametern".

Code: [AUSKLAPPEN]
Global count ;Hier erstellst du Count, da drin speichern wir den Fortschritt des Progbars
;dieser ist nun Global, d.h auch in Unterprogrammen da
window = CreateWindow("Window", 0, 0, 200, 100, 0, 1)
x = ClientWidth(window)
progbar = CreateProgBar(10, 10, x - 20, 20, window)
timer = CreateTimer(5)


Repeat
   If KeyHit(1) = 1 Then End
    If WaitEvent(0) = $4001 Then ;Wenn etwas getickt hat
           If EventSource() = timer And count<= 10 Then ;und es wirklich unser "timer" ist
         updatebar(progbar) ;Funktion updatebar aufrugen, mit dem Parameter progbar (siehe oben bei create progbar)
      EndIf
   EndIf
   
Forever


Function updatebar(bar_handle) ;Nun hier die funktion, in der Klammer steht bar_handle, dort drinn steht nun das was wir dort oben eingegeben haben, nämlich der Wert von progbar, also sein handle
    count = count + 1 ;jetzt erhöhen wir den Wert von count
     UpdateProgBar bar_handle, Float#(count) / 10 ; und updaten den progbar
End Function
   



So hast du den Vorteil, das du diese Function auf mehrere Progbars anwenden kannst, ist natürlich auch viel eleganter!

Kurze Erklärung zu "Handle", wenn du dich fragst was das sein soll
Jedes Gadget das du erstellst, ein Fenster, ein Button usw bekommt seine eigene ID, also eine Nummer mit der man das Gadget ansprechen kann, da es nun blöd ist diese Werte auswendig zu lernen, bekommen die eine Variable (zmb durch die Zuweisung fenster=CreateWindow)
Darum sind die Gadgets auch nicht einfach so ansprechbar in der Function/Unterprogramm.

Führ mal den Code aus
Code: [AUSKLAPPEN]
window = CreateWindow( "Test", 0, 0, 640, 480 )
Notify window


er gibt dir ne Zahl aus, dies ist der Handle Wink
Anstatt nun dein Fenster mit "windows" anzusprechen, könntest auch die Zahl eingeben,
das Problem ist, das bei jedem Programmstart ein neuer Handle erstellt wird


So, da du nun das Grundwissen hast xD
Zu deinem Problem

Code: [AUSKLAPPEN]
Global count
window = CreateWindow("Window", 0, 0, 200, 100, 0, 1)
x = ClientWidth(window)
Global progbar = CreateProgBar(10, 10, x - 20, 20, window)
timer = CreateTimer(5)


Repeat
   If KeyHit(1) = 1 Then End
    If WaitEvent(0) = $4001 Then
     If EventSource() = timer And count<= 10 Then
   updatebar()
   EndIf
   EndIf
   
Forever


Function updatebar()
    count = count + 1
     UpdateProgBar progbar, Float#(count) / 10
End Function


Das funktioniert ohne Probleme, ich denke du hast dich iwo vertippt!


puh viel geschrieben, hoffe es hilft Very Happy
Anmerkung, Code von der Onlinehilfe, angepasst.


Mfg ozzi Smile
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5
 

x_to

BeitragDo, Nov 26, 2009 17:49
Antworten mit Zitat
Benutzer-Profile anzeigen
yep....der fehler war so banal, daß es mir fast peinlich ist zu schreiben was es war....

ich habe vergessen aus dem zähler eine float zu machen.... Rolling Eyes

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group