Page 1 of 1

An alternative to FastFile...

Posted: Wed Aug 25, 2004 3:57 pm
by Alberto
Code updated For 5.20+

Below is an example of useful functions to use in alternative of FastFile library made by Rings.

The FastFile library made by Rings is amazing and surely better than my poor code but consider that:
- With this code you don't depend from any libraries because it's all made with PB internal commands.
- Maybe this code works well also on Linux while FastFile works only on windows (please Linux users tell me if this is true...)
- This code is really simple and you have only to add the prefix FF_ on your Fred's commands while on FastFile you have to manage an extra Offset variable.

Code: Select all

#FILE = 1
Global FFstart.l
Global FFpos.l
Global FFposmax.l
Global FF_EOF.l

Procedure FF_Write_Init()
  FFstart = AllocateMemory(101000)    ;Alloco 1Kbyte in più per essere sicuro di non sforare e andare in crash
  FFpos = FFstart
  FFposmax = FFstart + 100000
EndProcedure

Procedure FF_Buffer_scrivi()
  WriteData(#FILE,FFstart, FFpos - FFstart)
  FFpos = FFstart
EndProcedure

Procedure FF_WriteLong(numero.l)
  If FFpos > FFposmax
    FF_Buffer_scrivi()
  EndIf
  PokeL(FFpos, numero)
  FFpos = FFpos + 4
EndProcedure

Procedure FF_WriteString(stringa.s)
  If FFpos > FFposmax
    FF_Buffer_scrivi()
  EndIf
  PokeS(FFpos, stringa)
  FFpos = FFpos + Len(Stringa) + 1
EndProcedure

Procedure FF_Buffer_leggi()
  If FF_EOF = #False
    If Eof(#File)
      FF_EOF = #True           
    Else
      coda.l = FFposmax - FFpos
      If coda > 0
        ;Debug "Coda = " + Str(coda)
        CopyMemory(FFpos,FFstart,coda)  ;Copio la coda dei dati
      Else   
        ;Debug "non copio la coda"   
      EndIf
      FFposmax = ReadData(#FILE,FFstart + coda, 100000 - coda) + FFstart + coda
      FFpos = FFstart
    EndIf
  EndIf
EndProcedure

Procedure FF_Read_Init()
  FFstart = AllocateMemory(101000)    ;Alloco 1Kbyte in più per essere sicuro di non sforare e andare in crash
  FFposmax = FFpos   ;Mi serve per evitare di copiare la "coda2 dei dati alla prima volta
  FF_EOF = #False
  FF_Buffer_leggi()
EndProcedure

Procedure.l FF_ReadLong()
  If FFpos > (FFposmax - 1000)
    FF_Buffer_leggi()
  EndIf
  risultato.l = PeekL(FFpos)
  FFpos = FFpos + 4
  ProcedureReturn risultato
EndProcedure

Procedure.s FF_ReadString()
  If FFpos > (FFposmax - 1000)
    FF_Buffer_leggi()
  EndIf
  risultato.s = PeekS(FFpos)
  FFpos = FFpos + Len(risultato) + 1
  ProcedureReturn risultato
EndProcedure

Procedure FF_Read_Close()
  FreeMemory(FFstart)
EndProcedure

Procedure FF_Write_Close()
  FF_Buffer_scrivi()
  FreeMemory(FFstart)
EndProcedure

CreateFile(#File, "C:\Test_with_FF.txt")
Start.l = ElapsedMilliseconds()
FF_Write_Init()
For index = 1 To 1000000
  FF_WriteLong(index)   
Next
FF_Write_Close()
CloseFile(#File)
Debug "milliseconds used to write C:\Test_with_FF.txt = " + Str(ElapsedMilliseconds() - Start)

OpenFile(#File, "C:\Test_with_FF.txt")
Start.l = ElapsedMilliseconds()
FF_Read_Init()
For index = 1 To 1000000
  trash.l  = FF_ReadLong()
Next
FF_Read_Close()
CloseFile(#File)
Debug "milliseconds used to read C:\Test_with_FF.txt = " + Str(ElapsedMilliseconds() - Start)

CreateFile(#File, "C:\Test_without_FF.txt")
Start.l = ElapsedMilliseconds()
For index = 1 To 1000000
  WriteLong(#FILE,index)   
Next
CloseFile(#File)
Debug "milliseconds used to write C:\Test_without_FF.txt = " + Str(ElapsedMilliseconds() - Start)

OpenFile(#File, "C:\Test_without_FF.txt")
Start.l = ElapsedMilliseconds()
For index = 1 To 1000000
  trash.l  = ReadLong(#FILE)
Next
CloseFile(#File)
Debug "milliseconds used to read C:\Test_without_FF.txt = " + Str(ElapsedMilliseconds() - Start)

Debug "I think that is better using the FF functions..."

The code is based on the idea to use a buffer of 100Kbyte in memory where you write or read and accessing the file only using the ReadData/WriteData instructions that are quicker than ReadLong/WriteLong or ReadString/WriteString.

Maybe I've reinvented the wheel but I hope that is useful to someone.

The FastFile is surely more powerful and complete (I've not FastFileCRC32 for example) but if you only need to improve the speed of Fred's command I think that these functions are for you.

Feel free to copy it and tell me suggestion or improvement.

Alberto

Posted: Fri Aug 27, 2004 5:00 pm
by Psychophanta
The code is based on the idea to use a buffer of 100Kbyte in memory where you write or read and accessing the file only using the ReadData/WriteData instructions that are quicker than ReadLong/WriteLong or ReadString/WriteString.
I use that method in my file comparing program, but i am not able tu win to the Microsoft "FC" DOS command comparing speed. :cry:

Posted: Mon Aug 30, 2004 7:15 am
by Alberto
To see the speed comparing it's sufficient to execute the code that I've posted. The last lines in my code show the different times of execution in the debug window. It's very easy.

If you want it's easy to produce a MessageRequester instead of my debug commands.

Ciao
Alberto

Posted: Mon Jan 31, 2005 3:57 am
by Shannara
Ouch! I was looking for an alturnative for Ring's FastFile, as it is confusing as hell, and ran across yours. Unfortunately, It does not read bytes nor words, so there is no way I can use it.

Posted: Mon Jan 31, 2005 7:52 am
by Bonne_den_kule
Shannara wrote:Ouch! I was looking for an alturnative for Ring's FastFile, as it is confusing as hell, and ran across yours. Unfortunately, It does not read bytes nor words, so there is no way I can use it.
Look at his code. It's easy to change the code to write/read bytes and words

Posted: Mon Jan 31, 2005 9:22 am
by blueznl
yeah, i did something similar in x_openfile / x_readbyte etc. but somehow mine is quite a bit slower... i think :-)

have to test it...