Read text file is very slow

Just starting out? Need help? Post your questions and find answers here.
moob
User
User
Posts: 68
Joined: Mon Aug 01, 2011 6:16 pm

Read text file is very slow

Post by moob »

hi...

this code are slow reading 8940 lines of text to ListIcon.

made some mistake to be so slow???

here is text file: http://www.mediafire.com/?tdpzkb2bvhulwpr

anyone can text this.

thanks...

Code: Select all


Procedure OpenPlayerLista(*retinort)
  Pattern$ = "playerlist.txt (*.txt)|playerlist.txt"
  Pattern = 0
  FileR$ = OpenFileRequester("Please choose the playerlist...", "", Pattern$, Pattern)
  If OpenFile(6, FileR$)
    If ReadFile(6, FileR$)   ; if the file could be read, we continue...
      ClearGadgetItems(#ListIcon_41)
      StatusBarText(#StatusBar_wndMain, 1, "Loading Playerlist wait...", #PB_StatusBar_Center)
      DisableMenuItem(#Menu_wndMain, #Menu_wndMain_OpenPlayerlist, 1) 
      IDN = 0
      length = Lof(6)
      While Eof(6) = 0 
        IDN = IDN + 1
        Texto$ = Trim(ReadString(6)) 
        NomesID$ = Trim(StringField(Texto$, 1, ":"))
        NsID$ = Trim(StringField(Texto$, 2, ":"))
        StatusBarProgress(#StatusBar_wndMain, 2, Loc(6) , #PB_StatusBar_Raised, 0,length)
        AddGadgetItem(#ListIcon_41, -1, Str(IDN)+Chr(10)+NomesID$+Chr(10)+NsID$)
      Wend
      CloseFile(6)
      DisableMenuItem(#Menu_wndMain, #Menu_wndMain_OpenPlayerlist, 0) 
      StatusBarText(#StatusBar_wndMain, 2, "PlayerList Load Successfully", #PB_StatusBar_Center)
      StatusBarText(#StatusBar_wndMain, 1, "PlayerList Loaded", #PB_StatusBar_Center)
    EndIf
  EndIf
EndProcedure



User avatar
Kiffi
Addict
Addict
Posts: 1484
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: Read text file is very slow

Post by Kiffi »

this is a little bit faster:

Code: Select all

    HideGadget(#ListIcon_41, #True) ; <--- !
    While Eof(6) = 0 
        [...]
    Wend
    HideGadget(#ListIcon_41, #False) ; <--- !
and: you don't need the OpenFile()-Line

Greetings ... Kiffi
Hygge
moob
User
User
Posts: 68
Joined: Mon Aug 01, 2011 6:16 pm

Re: Read text file is very slow

Post by moob »

Kiffi wrote:this is a little bit faster:

Code: Select all

    HideGadget(#ListIcon_41, #True) ; <--- !
    While Eof(6) = 0 
        [...]
    Wend
    HideGadget(#ListIcon_41, #False) ; <--- !
and: you don't need the OpenFile()-Line

Greetings ... Kiffi
yes is little bit, but continues slowly

if i disable is the same :(

thanks Kiffi
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Re: Read text file is very slow

Post by Arctic Fox »

Try replacing this line

Code: Select all

Texto$ = Trim(ReadString(6)) 
with

Code: Select all

Texto$ = ReadString(6) 
The Trim() isn't necessary for Texto$ since you trim NomesID$ and NsID$ later.

Also consider only updating the status progress bar for example every tenth line.

Code: Select all

If IDN % 10 = 0 : StatusBarProgress(#StatusBar_wndMain, 2, Loc(6) , #PB_StatusBar_Raised, 0,length) : EndIf
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Read text file is very slow

Post by netmaestro »

Try this, you'll have to point it to your textfile:

Code: Select all

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)

ListIconGadget(0,0,0,300,400,"Number",140,#PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Name", 156)

ButtonGadget(1, 100,410,80,20,"Load")

Repeat
  EventID = WaitWindowEvent()  
  Select EventID
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SendMessage_(GadgetID(0), #WM_SETREDRAW, 0,0)
        If ReadFile(0, "c:\playerlist.txt")
          length = Lof(0)
          While Not Eof(0)
            Texto$ = Trim(ReadString(0)) 
            NomesID$ = Trim(StringField(Texto$, 1, ":"))
            NsID$ = Trim(StringField(Texto$, 2, ":"))
            StatusBarProgress(0, 0, Loc(0) , #PB_StatusBar_Raised, 0, length)
            AddGadgetItem(0, -1, NomesID$+Chr(10)+NsID$)
          Wend
        EndIf
        SendMessage_(GadgetID(0), #WM_SETREDRAW, 1, 0)
      EndIf
  EndSelect
  
Until EventID = #PB_Event_CloseWindow
BERESHEIT
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Read text file is very slow

Post by ts-soft »

A faster version of netmaestros code:

Code: Select all

EnableExplicit

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)

ListIconGadget(0,0,0,300,400,"Number",140,#PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Name", 156)

ButtonGadget(1, 100,410,80,20,"Load")

Define EventID, length, *mem, Text.s, Count, i
Define tmp.s, NomesID$, NsID$

Repeat
  EventID = WaitWindowEvent() 
  Select EventID
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SendMessage_(GadgetID(0), #WM_SETREDRAW, 0,0)
        If ReadFile(0, "c:\playerlist.txt")
          length = Lof(0)
          *mem = AllocateMemory(length)
          If *mem
            ReadData(0, *mem, length)
            CloseFile(0)
            Text = PeekS(*mem, length, #PB_UTF8)
            FreeMemory(*mem)
            RemoveString(Text, #CR$)
            Count = CountString(Text, #LF$)
            For i = 1 To count
              tmp = StringField(Text, i, #LF$)
              NomesID$ = Trim(StringField(tmp, 1, ":"))
              NsID$ = Trim(StringField(tmp, 2, ":"))
              StatusBarProgress(0, 0, i, #PB_StatusBar_Raised, 0, count)
              AddGadgetItem(0, -1, NomesID$ + Chr(10) + NsID$)
            Next
          EndIf

        EndIf
        SendMessage_(GadgetID(0), #WM_SETREDRAW, 1, 0)
      EndIf
  EndSelect
 
Until EventID = #PB_Event_CloseWindow
Reading the text at ones in memory is always faster than line by line.

Greetings - Thomas
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Read text file is very slow

Post by rsts »

In my experience, building/displaying a 9000 item listicongadget is a little slow even if everything is in memory.

There is a way to do it almost instantly, but it's not a standard PB listicongadget.

cheers
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Read text file is very slow

Post by netmaestro »

Let's strap a nice ACME rocket to the back of this coyote:

Code: Select all

#LVSICF_NOINVALIDATEALL = 1 
#LVN_ODCACHEHINT = #LVN_FIRST - 13

Global Dim Items.s(9000,2) 

If ReadFile(0, "c:\playerlist.txt")
  length = Lof(0)
  IDN=0
  While Not Eof(0)
    Items(IDN, 0) = Str(IDN)
    Texto$ = Trim(ReadString(0)) 
    Items(IDN, 1) = Trim(StringField(Texto$, 1, ":"))
    Items(IDN, 2) = Trim(StringField(Texto$, 2, ":"))
    IDN + 1
  Wend
  CloseFile(0)
Else
  Debug "Could not open the file!"
EndIf

Procedure WinProc(hwnd, msg, wParam, lParam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lParam 
      Select *pnmh\code 
        Case #LVN_ODCACHEHINT 
          result = 0  
        Case #LVN_GETDISPINFO 
          *pnmlvdi.NMLVDISPINFO = lParam 
          If *pnmlvdi\item\mask & #LVIF_TEXT = #LVIF_TEXT
            *pnmlvdi\item\pszText = @Items(*pnmlvdi\item\iItem, *pnmlvdi\item\iSubItem) 
          EndIf 
      EndSelect 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowCallback(@WinProc(),0) 
ListIconGadget(0,0,0,300,400,"Number",50,#PB_ListIcon_GridLines|#LVS_OWNERDATA) 

SendMessage_(GadgetID(0), #LVM_SETITEMCOUNT, IDN, #LVSICF_NOINVALIDATEALL) 
AddGadgetColumn(0, 1, "ID",   60) 
AddGadgetColumn(0, 2, "Name", 140) 

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Thanks to Sparkie for guidance and hints from here: http://www.purebasic.fr/english/viewtop ... 38&start=4
BERESHEIT
moob
User
User
Posts: 68
Joined: Mon Aug 01, 2011 6:16 pm

Re: Read text file is very slow

Post by moob »

thanks guys...

the netmaestro is fast and ts-soft too.


thanks to all
User avatar
oryaaaaa
Addict
Addict
Posts: 825
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Re: Read text file is very slow

Post by oryaaaaa »

Fast reading method
1. ReadData use All text data
2. List Buffer use separeting text data
3. Foreach next

Code: Select all

Procedure OpenPlayerLista(*retinort)
  ; You must use Protected, coz safety
  Protected Pattern.s, Pattern_no.l, FileR.s, IDN.l, length.l, Texto.s, NomesID.s, NsID.s
  Protected *TextBuffer, TextPos, File.l
  Protected NewList TextBuffer.s()
  ; 1st Read All data to Memory
  Pattern = "playerlist.txt (*.txt)|playerlist.txt"
  Pattern_no = 0
  FileR = OpenFileRequester("Please choose the playerlist...", "", Pattern, Pattern_no)
  ; FileSize_check
  If FileSize(FileR)>0
    ClearGadgetItems(#ListIcon_41)
    StatusBarText(#StatusBar_wndMain, 1, "Loading Playerlist wait...", #PB_StatusBar_Center)
    DisableMenuItem(#Menu_wndMain, #Menu_wndMain_OpenPlayerlist, 1) 
    ; My Tips, Very fast
    File = ReadFile(#PB_Any, FileR)
    length = Lof(File)
    *TextBuffer = AllocateMemory(length)
    ReadData(File, *TextBuffer, length)
    CloseFile(File) 
    ; If FASM use, more fast. -1 is abc chr13+10. 0 is abc chr13+10 def.
  SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS) 
    For TextPos = 0 To CountString(PeekS(*TextBuffer,length), Chr(13)+Chr(10))-1
      AddElement(TextBuffer())
      TextBuffer() = StringField( PeekS(*TextBuffer,length,#PB_UTF8), TextPos, Chr(13)+Chr(10) )
    Next
    FreeMemory(*TextBuffer)
    ; This is Safety.
    ForEach TextBuffer()
      TextBuffer() = Trim( TextBuffer() )
      NomesID = Trim( StringField( TextBuffer(), 1, ":") )
      NsID = Trim( StringField( TextBuffer(), 2, ":") )
      AddGadgetItem(#ListIcon_41, -1, Str( ListIndex( TextBuffer() ) )+Chr(10)+NomesID+Chr(10)+NsID)
    Next
  SetPriorityClass_(GetCurrentProcess_(),NORMAL_PRIORITY_CLASS) 
    DisableMenuItem(#Menu_wndMain, #Menu_wndMain_OpenPlayerlist, 0) 
    StatusBarText(#StatusBar_wndMain, 2, "PlayerList Load Successfully", #PB_StatusBar_Center)
    StatusBarText(#StatusBar_wndMain, 1, "PlayerList Loaded", #PB_StatusBar_Center)
  EndIf
EndProcedure
Last edited by oryaaaaa on Fri Jan 13, 2012 9:58 am, edited 1 time in total.
Fred
Administrator
Administrator
Posts: 18153
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Read text file is very slow

Post by Fred »

I don't think then readstring() is the bottleneck here, since a while all file operation are heavily cached by PureBasic for maximum efficiency. You can still put a larger internal filebuffer if you think it could help: http://www.purebasic.com/documentation/ ... ssize.html
User avatar
oryaaaaa
Addict
Addict
Posts: 825
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Re: Read text file is very slow

Post by oryaaaaa »

Danger Tips
coz
Return value : This function has no return value.

"Invalid memory Accesss error" never?

I used FileBuffersSize() before, but very slow.
Benchmark test result ReadData win.
Vitor_Boss®
User
User
Posts: 81
Joined: Thu Sep 23, 2010 4:22 am

Re: Read text file is very slow

Post by Vitor_Boss® »

In my application the ReadData() is 3-5 times faster than ReadText().

For this kind of application I use 2 procedures, one to get the text file and another to split a delimiter with unlimited size.

Seems the author of the thread speak portuguese, I have some code here if you want.
Sorry by bad English.
HP Pavilion DV6-2155DX: Intel i3-330m 2.13 / 4GB DDR3 / 500GB Sata2 HD / Display 15.6" LED / Win7 Ultimate x64 / PB 4.50 x86 demo.
Post Reply