große Dateien speichern

Übersicht BlitzBasic Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

DirkKnoop

Betreff: große Dateien speichern

BeitragMi, Apr 01, 2015 18:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich möchte beispielsweise Daten in eine .txt-Datei speichern, in der Millionen von Zahlen und Wörtern stehen.
Das Speichern und Laden dieser Datei dauert ca. 1 Minute.

Ist es möglich, dieses zu beschleunigen, beispielsweise mittels .rar oder .zip ?
Oder hat jemand eine andere Idee ?

Vielen Dank schon einmal,
Dirk

BladeRunner

Moderator

BeitragMi, Apr 01, 2015 19:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Das unkomprimierte Speichern sollte die flotteste Variante sein. zip und rar generieren ja einen ziemlichen Zeitaufwand beim packen / entpacken.
Du könntest, falls technisch machbar, die Datei in kleine Happen zerlegen und nach und nach im Hintergrund laden.
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

Pummelie

BeitragMi, Apr 01, 2015 20:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Laden von diesen Daten wird durch den Flaschenhals Festplatte ausgebremmst, dein Ansatz es auf die CPU zu schieben der Flaschenhals zu sein ist denke ich mal nicht zielführend.

Ich würde schauen in wie fern die Daten überhaupt relevant sind. Wenn du nicht alle Daten permanent brauchst würde ich diese in Sektionen einteilen und bei bedarf nachladen.
It's done when it's done.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Apr 01, 2015 21:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Edit1:

Um welche Datenmengen reden wir den überhaupt?
 

DirkKnoop

BeitragDo, Apr 02, 2015 4:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

insgesamt sind es ca. 75 MB für eine Datei.
Meist steht in einer Zeile einfach nur eine Ziffer, ansonsten ein Wort mit bis zu 100 Buchstaben.
Insgesamt sind es ca. 21.500.000 Zeilen.

Dirk

Eingeproggt

BeitragDo, Apr 02, 2015 9:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Das heißt du könntest mit der Verwendung von WriteByte anstelle von WriteLine bei jeder Ziffer 2 Byte (Zeilenumbruch auf Windows) sparen.
Allerdings musst du dann genau festlegen, wo eine Ziffer (Byte) steht und wo ein Wort (String / Textzeile) steht.

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

DirkKnoop

BeitragDo, Apr 02, 2015 11:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

das wäre Mist - da ich es leider nicht immer weiß.
Schade...Wenn ich die .txt-Datei mit winrar packe, dauert dieses nur 2 Sekunden - und die Datei ist statt 75 MB nur 2,4 MB groß.

Meint ihr nicht, dass pass die Datei mit Blitz3D und irgendeiner Lib im Speicher packen kann ?
Habe damit leider gar keine Ahnung.

Dirk

Xeres

Moderator

BeitragDo, Apr 02, 2015 13:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du an den Inhalt der Datei kommen willst, dann kann es nicht schneller sein, die Datei erstmal entpacken zu müssen.
Üblicherweise muss man zwischen Speicherverbrauch und Geschwindigkeit abwägen: Entweder es soll schnell gehen und man benutzt Header/Indizies um an die richtigen Daten zu kommen, oder man möchte möglichst wenig speichern und benutzt einen komprimieralgorithmus, der seine Zeit braucht.

Es kommt darauf an, wie du mit den Daten umgehst... Du liest erst mal 21 Mio. Zeilen einzeln mit BB ein? Natürlich dauert das ewig (allein schon den RAM zu reservieren)! Du liest den Header, springst du einem Block in der Datei und liest nur die eine Zeile aus, die du brauchst? Super schnell.

Unstrukturierte Daten wird man nie schnell laden und verarbeiten können...
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

DAK

BeitragDo, Apr 02, 2015 13:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Doch doch, das könnte schon gehen. Wenn die Festplatte langsam ist und die CPU schnell, dann kann man schon einen Performance-Boost haben, wenn man einen sehr einfachen und somit schnellen Komprimierungsalgo verwendet, wie z.B. ZIP. Vor allem dann, wenn es sich bei den Daten um was Hochkomprimierbares handelt, wie simpler Text. Ein PNG laden ist ja auch nicht langsamer als ein BMP, sondern eher schneller.

Wenn du dich nicht davor scheust, DLLs zu verwenden und DECLS selber zu schreiben, dann schau dir mal Libarchive an, das sollte können, was du brauchst.
Gewinner der 6. und der 68. BlitzCodeCompo

Dottakopf

BeitragDo, Apr 02, 2015 16:19
Antworten mit Zitat
Benutzer-Profile anzeigen
für mich klingt das eher nach einem Konzeptfehler.
Was genau beinhaltet die Datei für Daten? wann rufst du diese ab?


Wie alle vorher bereits erwähnt haben wäre wohl Nachladen, oder gar auslagern auf verschiedene Files(wenn start bzw. pos nicht bekannt) sinnvoll.

75 MB in einer Textfile ist recht viel. Evt. wäre eine Datenbank die richtige Lösung..
Zitat:
Meinst nur eine Ziffer, oder ein Wort
ladest du Accountdaten Smile ?
Rechtschreibfehler gelten der allgemeinen Belustigung!
 

DirkKnoop

BeitragDo, Apr 02, 2015 16:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

es handelt sich bei einem Fußballmanager (www.torchance.de) zu ca. 90 % um Eigenschaften von Fußballspielern, die im Spiel "täglich" geändert werden (können).

Also deren Namen, Anzahl der Tore, Frischewerte, Anzahl der gelben Karten, Geburtstag usw.

In 198 Ländern werden jeweils ca. 18 Vereine mit jeweils ca. 25 Spielern simuliert.
Jeder Spieler hat sehr viele Eigenschaften.

Dirk

Eingeproggt

BeitragDo, Apr 02, 2015 16:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würd nach wie vor an der Idee einer "binärdatei" festhalten.
Also nicht alles in lesbarem Text schreiben, sondern in computer-lesbaren Bytes (oder Floats, Ints).
Das verbraucht viel weniger Platz, du ersparst dir die Konvertierungen (weiß nicht wie schnell da BB ist wenn man implizit zB punkte#="123.456" verarbeiten lässt...)
Und du weißt sehr wohl welchen Datentyp ein Spieler-Attribut hat. Also vereinfacht gesagt:
spieler\name = ReadString(reader)
spieler\alter = ReadByte(reader)
...
und umgekehrt in der Reihenfolge auch speichern und du hast dein eigenes Datei-Format wo ich wetten möchte dass es plötzlich (ohne Kompressions-Algorithmen) nur noch ~30mb sind.

Unabhängig davon könnte man die Datei wohl wirklich "stückweise" nachladen. Also die Spieler eines Landes erst laden, wenn das Land geöffnet wird usw. Dauert dann pro Land wohl nur noch 1sek und fertig.

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

DirkKnoop

BeitragDo, Apr 02, 2015 17:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

das Problem mit dem "stückchenweise" ist eher das Speichern - sprich der Spieler möchte das Spiel beenden, speichert seinen Spielstand und das Spiel endet.
Das muss ja alles auf einmal gespeichert werden Wink

Dirk

Xeres

Moderator

BeitragDo, Apr 02, 2015 17:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum bist du der Auffassung, dass das, was der Spieler macht, Einfluss auf die Art deiner Datenhaltung hat?
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

DAK

BeitragDo, Apr 02, 2015 17:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, da gibt es ein paar bessere Möglichkeiten als gezipt zu speichern. Eine Datenbank wäre da schon ganz sinnvoll. Wieviel Prozent der Daten ändert sich denn jeden Spieltag? Ich denke, z.B. Name und Geburtstag wird recht stabil sein.

Wenn du willst, dann kannst du deine Datenbank auch in Dateien lösen. Sinnvoll wäre es z.B. so:

Datei 1: Permanente Daten
Hier kommen alle Daten rein, die sich nicht ändern:
SpielerID, Name, Geburtstag, ...

Diese Datei fasst du nicht mehr an. Kannst sie ruhig in Zeilen-/Stringformat schreiben.

Datei 2: Änderbare Binärdaten
Hier kommen alle sich änderbaren Zahlen rein. Die Datensätze haben immer das gleiche Format, brauchen also keinen Header oder Deskriptor. Schreiben und Lesen machst du über WriteInt/WriteFloat/ReadInt/ReadFloat, bzw Short oder Byte, je nach dem Wert. Du schreibst immer die gleichen Werte in der gleichen Reihenfolge pro Eintrag in den Datensatz. Ein Int/Float-Wert braucht hier immer genau 4 Byte, nicht bis zu 11 Byte wie wenn du die Zahlen als String abspeicherst.

Datei 3: Änderbare Strings
Diese Datei ist wohl die Kritischste, falls du sie brauchst. Hier schreibst du alle änderbaren Strings im Zeilenformat rein.

Ich nehme an, wenn du das umsetzt, dann kommst du sicher auf weniger als ein Viertel der regelmäßig zu speichernden Daten.

Dann noch zu dem was Xeres sagt: Du kannst jederzeit mitspeichern. Speicher es hald in einen zweiten Datensatz nach jedem Tag (kannst es mit 20 Zeilen pro Frame oder so machen, dann merkts der Spieler nicht). Wenn er dann speichern will, alles was du dann noch machen musst ist das alte File löschen und das Neue umzubenennen. Das geht quasi sofort.
Gewinner der 6. und der 68. BlitzCodeCompo

Dottakopf

BeitragDo, Apr 02, 2015 18:09
Antworten mit Zitat
Benutzer-Profile anzeigen
wäre eine tolle code combo aufgabe Very Happy

Dak hat dir einen tollen ansatz geliefert.
Ergänzen möchte ich noch, das du mit deiner mega datei davon ausgehst das der Spielende sofort alle Spielerdaten aktuell sehen will. Du hast Manschaften danach kannst du es doch auch ganz simpel unterteilen und auch Updaten.

Ist er im "Team Management" öffnest du nur die Datei mit der jeweilig ausgewählten manschaft. Schließlich interesiert das den Spieler im Moment auch nur. Wechselt er zu einer anderen Manschaft öffnest du diese File.
Diese mini-Manschaft-infos müssen natürlich optimiert erstellt werden, Writebyte, Writestring..
Mithilfe einer Prüfsumme(muss bei Updates natürlich angepasst werden) kannst du die Dateien auch recht simpel vor Manipulation schützen.


Beginnt eine Partie musst du auch wieder nur 2 Manschaft files öffnen. Sollte eigentlich auch ganz fix sein.
Rechtschreibfehler gelten der allgemeinen Belustigung!

BtbN

BeitragDo, Apr 02, 2015 18:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Les die gesamte Datei in einem aufruf in eine Bank, und parse dann die Bank.
So kann die Festplatte einem großen sequentiellen read machen der in unter einer sekunde erledigt sein sollte.
75MB Daten im RAM parsen geht auch ohne merkbare verzögerung, wenn du nicht völligen Unsinn fabrizierst.

75MB ist nicht viel, alles was mit Videos zu tun hat hantiert mit _wesentlich_ umfangreicheren Datenmengen ohne dabei die an die grenze der Platten-Geschwindigkeit zu stoßen.
 

Kruemelator

BeitragDo, Apr 02, 2015 18:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn eine große Menge an Daten aus einer Datei geladen werden müssen kann es sich lohnen erst einmal alles in den Speicher zu laden. Also ermittel wie viel Speicherplatz benötigt wird, eine Bank erstellen und EINMAL ReadBytes nutzen.
Dies kannst du mit den Vorschlägen von DAK kombinieren.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDo, Apr 02, 2015 21:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube eher, dass es sich um ein organisatorisches Problem handelt. Habe eben mal folgendes ausprobiert.

1.) Eine BMP (RGB = 24 Bit) mit einer Kantenlänge von 5120x5120 ~75MB Rohdaten als eben solche zu laden und per Read- und WritePixelFast jeden Pixel entsprechend zu ändern und in einer neuen BMP per SaveImage zu speichern. Bearbeitungszeit etwa 4 Sekunden.

2.) Eine Datei mit 75MB per ReadInt zu laden, ändern und wieder per WriteInt zu speichern. Und hier beträgt ebenfalls die Bearbeitungszeit etwa 4 Sekunden.

Um nun auszuschließen dass meine Datei sich noch im Chache befindet, habe ich mein Rechner aus- und dann wieder eingeschaltet und anschließend als erstes das B3D-Programm gestartet. Hier konnte man nun auf einmal deutlich das rattern der alten und extra langsamen dafür recht leisen 1GB Festplatte hören. Bearbeitungszeit nun etwa 6 Sekunden beim Versuchsaufbau aus Punkt zwei.

Edit1:

1.) Code: [AUSKLAPPEN]
Graphics 480,360,0,2
SetBuffer FrontBuffer()

Local Inhalt,Test,Buffer,X,Y,I,ARGB,R,G,B
Inhalt=LoadImage("d:\Tokyo.bmp")
Buffer=ImageBuffer(Inhalt)
LockBuffer Buffer

For Y=0 To 5119
   For X=0 To 5119
      ARGB=ReadPixelFast(X,Y,Buffer)
      R=(ARGB And $FF0000) Shr 16;/$10000
      G=(ARGB And $FF00)Shr 8;/$100
      B=(ARGB And $FF)
      
      R=R+Rand(-2,+2)
      G=G+Rand(-2,+2)
      B=Rand(0,255)
      
      ARGB=R*$10000+G*$100+B
      
      WritePixelFast X,Y,ARGB,Buffer
   Next
Next

UnlockBuffer Buffer

If SaveImage(Inhalt,"d:\Tokyo1.bmp")=1 Then
   Print "ok!"
Else
   Print "Fehler"
End If

Delay 1000

2.) Code: [AUSKLAPPEN]
Graphics 480,360,0,2
SetBuffer FrontBuffer()

Local Size=FileSize("d:\Tokyo.bmp")
Local File1=ReadFile("d:\Tokyo.bmp")
Local File2=WriteFile("d:\Tokyo2.bmp")
Local ARGB,Count=0

While Not Eof(File1)
   Count=Count+1
   ARGB=ReadInt(File1)
   If Count>1024 Then ARGB=ARGB+Rand(-200,+200)
   WriteInt(File2,ARGB)
Wend

CloseFile(File1)
CloseFile(File2)

Print "DURCHFÜHRUNG"

Delay 1000

Es gilt zu vermeiden, Stringbefehle auszuführen. Deutlich schneller sind direkte Byteoperationen. Wenn ein vernünftiger Header erstellt wird, ist die Organisation auch kein Problem und auch nichts zu langsam. DAK hat es schon gut beschrieben.

Thunder

BeitragDo, Apr 02, 2015 23:17
Antworten mit Zitat
Benutzer-Profile anzeigen
@Topic
Naja du sagst die Datei ist etwa 75 MB groß und hat etwa 21.500.000 Zeilen. Das heißt, ca 41 MB der Datei besteht nur aus Zeilenumbrüchen. Wenn du Datensätze die zusammengehören in eine einzelne Zeile zusammenfasst (z.B. durch ; getrennt), könntest du dir ein paar MB sparen(!)

Schau dir Mal die Lib an: https://www.blitzforum.de/foru....php?t=612

Ist schon sehr alt, aber die scheint auf Basis der zlib Banks zu komprimieren und dekomprimieren können.
Aber wenns nicht geht: Es gibt sicher genügend Kompressions-Libraries, die nur darauf warten entdeckt zu werden! Wink

Du wirst natürlich dann beim Laden die Probleme kriegen, weil du die komprimierte Datei in den RAM laden musst, dann wird die Mal in eine Bank dekomprimiert und dann musst du sie von dort aus parsen, was auch ein Flaschenhals sein wird - es sei denn du findest einen Weg, das in einem eigenen Thread im Hintergrund zu machen.

@Senf (weil ja jeder seinen dazugibt)
Kann schon sein, dass Komprimierung in diesem Fall wirklich die beste Lösung ist.
Ich bin in diesem Fall nicht wirklich für die Binärdaten-Methode von Eingeproggt, da es um einiges schwieriger ist ein Binärdatenformat zu erweitern, wenn man sich nicht im Vorhinein schon Erweiterungsgedanken macht. Die Textdaten kann ich einfach von einem Skript verarbeiten lassen (und wenn sie komprimiert sind, entpacke ich sie halt vorher und packe sie danach wieder).

Eine Datenbank ist in diesem Fall vielleicht angemessen. Ich schreibe das Programm nicht also kann ich es nicht beurteilen. Trotzdem habe ich mit Textdateien den Vorteil, dass es leichter zu handlen ist und ich mich nicht mit irgendeiner Datenbanksoftware herumschlagen muss.

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group