Page 2 of 2

Re: Array Search Procedure

Posted: Wed Nov 03, 2010 2:52 am
by cas
Vitor_Boss® wrote:The bigger problem is the time used to read the file, 33MB take about 1 Sec in exe mode and 9-12 Sec in debug mode.
How can I improve the read file speed? I'm reading one byte/time.Look:
Maybe this will help you: http://www.forums.purebasic.com/english ... 87#p336087

Re: Array Search Procedure

Posted: Wed Nov 03, 2010 9:33 pm
by Vitor_Boss®
cas wrote:
Vitor_Boss® wrote:The bigger problem is the time used to read the file, 33MB take about 1 Sec in exe mode and 9-12 Sec in debug mode.
How can I improve the read file speed? I'm reading one byte/time.Look:
Maybe this will help you: http://www.forums.purebasic.com/english ... 87#p336087
Now this take > 360ms to read a 33MB file.

Code: Select all

Procedure.b GetByte(FileName.s,Array Output.a(1), Size.l=0, START.l=0)
  Protected Status.a, i.l, length.l
  Protected Temp.s
  Define *MemoryID
  If FileSize(FileName)
    Status = OpenFile(1,FileName)
    If Status <> 0
      If Size = 0      
        Size = FileSize(FileName)
      EndIf    
      ReDim Output(Size)
      FileSeek(1,START)
      *MemoryID = @Output(0)
      If *MemoryID
        ReadData(1, *MemoryID, Size)
      EndIf
      CloseFile(1)
      ProcedureReturn Status
    Else
      ProcedureReturn Status
    EndIf
  EndIf  
EndProcedure

Re: Array Search Procedure

Posted: Thu Nov 04, 2010 12:12 am
by cas
You are doing it wrong, this code needs at least 66MB of RAM (ReDim + AllocateMemory()) to read complete 33MB file. Replace *MemoryID = AllocateMemory(Size) line with *MemoryID = @Output(0) so you won't do same thing twice. Look at code that i posted in other thread, i thought it would be perfect for your needs and it doesn't need so much RAM, it could probably run on computer with 32MB RAM+Windows 95 and do its job on 1GB file without crashing, which, with your code would crash immediately because it would need 2GB (1GB if you remove AllocateMemory()) of free RAM. If computer runs out of memory then your application will crash because you are not testing if ReDim failed or succedded with ArraySize(). And 360ms to read a 33MB file - that is relative and it doesn't mean anything, except if you have SSD and you are testing it with debugger disabled - in that case we could say it is slow. :)

Re: Array Search Procedure

Posted: Thu Nov 04, 2010 12:39 am
by Vitor_Boss®
Thank you very much for tell me how improve my code. Look the results:

Code: Select all

Advanced Patches Auto Porter v1.5.0.0
© 2010 Vitor_Boss®

Loaded Original Firmware (34MB) in 47ms
Loaded Destination Firmware (34MB) in 47ms
My notebook has a HD not a SSD.

Re: Array Search Procedure

Posted: Thu Nov 04, 2010 11:49 am
by blueznl
Perhaps you want to read it directly into a memory block with ReadData()?

Re: Array Search Procedure

Posted: Thu Nov 04, 2010 10:07 pm
by Vitor_Boss®
Yes, I'm trying build the fastest algorithm possible. Any idea to improve this code?

Code: Select all

Procedure.b GetByte(FileName.s,Array Output.a(1), Size.l=0, START.l=0)
  Protected Status.a, i.l, length.l
  Protected Temp.s
  Define *MemoryID
  If FileSize(FileName)
    Status = OpenFile(1,FileName)
    If Status <> 0
      If Size = 0
        Size = FileSize(FileName)
      EndIf
      ReDim Output(Size)
      FileSeek(1,START)
      *MemoryID = @Output(0)
      If *MemoryID
        ReadData(1, *MemoryID, Size)
      EndIf
      CloseFile(1)
      ProcedureReturn Status
    EndIf
  EndIf
  ProcedureReturn 0
EndProcedure

Re: Array Search Procedure

Posted: Fri Nov 05, 2010 2:56 am
by cas
Here i corrected your code (added check if ReDim failed) and removed unnecessary variables, but you could also add some checks to test if start position is not greater than length of file if you want.
You can't get any faster code than this one to read whole file to array. And i would never do it that way because of, previously mentioned, high RAM usage.

Code: Select all

Procedure GetByte(FileName.s,Array Output.a(1), Size=0, START=0)
  Protected FileHandle, Result
  If FileSize(FileName) > 0
    FileHandle = OpenFile(#PB_Any,FileName)
    If FileHandle <> 0
      If Size = 0
        Size = Lof(FileHandle)
      EndIf
      ReDim Output(Size)
      If ArraySize(Output.a()) <> -1
        FileSeek(FileHandle, START)
        ReadData(FileHandle, @Output(0), Size)
        Result=#True
      EndIf
      CloseFile(FileHandle)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Re: Array Search Procedure

Posted: Fri Nov 05, 2010 3:16 am
by Vitor_Boss®
Thank you, about RAM usage, I think don't need more RAM than the specified size.

Re: Array Search Procedure

Posted: Wed Nov 10, 2010 10:36 pm
by Vitor_Boss®
There is a new version of Tuned Boyer-Moore algorithm.

Code: Select all



Procedure TUNEDBM(Start.l,Array Source.a(1), Array Pattern.a(1))
   Protected.i i, j, m, n, k, match, shift
   Protected.i Dim bmBc(255)   
   m = ArraySize(Pattern())
   n = ArraySize(Source()) 
   ; Preprocessing 
   preBmBc(Pattern(), bmBc())
   shift = Max(bmBc(Pattern(m - 1)),1)
   bmBc(Pattern(m - 1)) = 0
   ; Searching
   j = Max(0,Start-1)
   While j < n
	  While j + m < n And bmBc(Source(j + m -1)) <> 0
	    j + bmBc(Source(j + m -1))
	    If j + m >= n : Break : EndIf
		  j + bmBc(Source(j + m -1))
	    If j + m >= n : Break : EndIf
		  j + bmBc(Source(j + m -1))
	    If j + m >= n : Break : EndIf
	  Wend
	  If CompareMemory(@Source(j), @Pattern(), ArraySize(Pattern()))
	    ProcedureReturn j
	  EndIf 	  
	  j + shift
	Wend
	ProcedureReturn 0
EndProcedure

Re: Fastest String/Array Search Procedure

Posted: Mon Nov 29, 2010 1:47 pm
by Vitor_Boss®
Fastest string find procedure.

Code: Select all

Removed

Re: Fastest String/Array Search Procedure

Posted: Mon Nov 29, 2010 10:57 pm
by Michael Vogel
What have to be done to do a fast string find? The following code needs times more execution time for the new routine...

Code: Select all

#FSText="llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllliiillllllllll"
#FSNumber=999999
x-ElapsedMilliseconds()
For i=0 To #FSNumber
    a=FindString(#FSText,"iii",1)
Next i
x+ElapsedMilliseconds()

y-ElapsedMilliseconds()
For i=0 To #FSNumber
    a=TunedFind(#FSText,"iii",1)
Next i
y+ElapsedMilliseconds()

MessageRequester("-",Str(x)+" vs. "+Str(y))