Why is Thread so slow?

Just starting out? Need help? Post your questions and find answers here.
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Why is Thread so slow?

Post by Polly »

Can anybody pls explain me why the thread in the following example is so slow compared to directly executing it:

Code: Select all

If OpenWindow(0, 216, 0, 602, 302, "PureLVSORT Test",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
   ListIconGadget(0, 5, 5, 590, 285, "String", 110)
   AddGadgetColumn(0, 1, "Numeric", 110)
   AddGadgetColumn(0, 2, "Float", 110)
   AddGadgetColumn(0, 3, "DateDDMMYYYY", 120)
   AddGadgetColumn(0, 4, "DateMMDDYYYY", 120)
   For i=1 To 500
      AddGadgetItem(0, -1, "ABCDE" + Chr(10) + "514" + Chr(10) + "0.9" + Chr(10) + "31/12/2004" + Chr(10) + "12/31/2004")
   Next
EndIf

Global start0=ElapsedMilliseconds()

Procedure test(x)
    n=CountGadgetItems(0)-1
    For i=0 To n
       For j=0 To 4
          out$+GetGadgetItemText(0,i,0)+#TAB$
       Next
       out$+GetGadgetItemText(0,i,0)+#CRLF$
       start1=ElapsedMilliseconds()
       Debug start1-start0
       start0=start1
    Next
    Debug Len(out$)
EndProcedure

Repeat
  Event = WaitWindowEvent()
  If event=#PB_Event_Gadget   ; just click
;    test(0)    ; 100x faster!
    t=CreateThread(@test(),0)
    While IsThread(t)
       ev=WindowEvent()  ; if this is removed thread doesn't work at all
       If Not ev: Delay(10) : EndIf
    Wend 
  EndIf
Until Event = #PB_Event_CloseWindow
Also strange that it requires the message queue whilst during direct run no msg handling is in place.

PB 4.31/XP
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

you should not seperate window handling on several threads.

all access to window objects should be placed within the same thread the concerning window is created and the eventloop is handled.
oh... and have a nice day.
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Post by helpy »

Try this:

Code: Select all

EnableExplicit

Define i, hThread, Event

If OpenWindow(0, 216, 0, 602, 302, "PureLVSORT Test",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
  ListIconGadget(0, 5, 5, 590, 285, "String", 110)
  AddGadgetColumn(0, 1, "Numeric", 110)
  AddGadgetColumn(0, 2, "Float", 110)
  AddGadgetColumn(0, 3, "DateDDMMYYYY", 120)
  AddGadgetColumn(0, 4, "DateMMDDYYYY", 120)
  For i=1 To 500
    AddGadgetItem(0, -1, "ABCDE" + Chr(10) + "514" + Chr(10) + "0.9" + Chr(10) + "31/12/2004" + Chr(10) + "12/31/2004")
  Next
EndIf

Procedure test( x )
  Protected start0, start1, n, i, j, out.s
  start0 = ElapsedMilliseconds()
  n = CountGadgetItems(0)-1
  For i = 0 To n
    For j = 0 To 4
      out + GetGadgetItemText( 0, i, 0 ) + #TAB$
    Next
    out + GetGadgetItemText( 0, i, 0 ) + #CRLF$
    start1 = ElapsedMilliseconds()
    Debug start1 - start0
    start0 = start1
  Next
  Debug "Length: " + Str( Len(out) )
EndProcedure

Repeat
  Event = WaitWindowEvent()
  If event=#PB_Event_Gadget   ; just click
    ; do not start new thread, if it is still running
    If Not IsThread( hThread )
      hThread = CreateThread( @test(), 0 )
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow
The problem was:

Code: Select all

    While IsThread(t)
       ev=WindowEvent()  ; if this is removed thread doesn't work at all
       If Not ev: Delay(10) : EndIf
    Wend
1. With this Loop (especially Delay(1)) you slow down the message loop and therfore also the message handling!

2. In the thread you call CountGadgetItems and GetGadgetItem! These calls send messages from the running thread to the main thread (where the messagehandling will take place). And only if the messagehandling can do its job the thread will get the answer! If you wait for the end of the thread (with While IsThread()) then the message loop will not get any message except you put the ev=WindowEvent() in the Wait-Loop.

You do not need to wait for the end of the thread ... let the thread do its thing, until its finished ... and let the message handling loop do its thing without waiting for the end of the thread.

cu, helpy
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Post by helpy »

another thing:

Code: Select all

  n = CountGadgetItems(0)-1
  For i = 0 To n
    For j = 0 To 4
      out + GetGadgetItemText( 0, i, 0 ) + #TAB$
    Next
    out + GetGadgetItemText( 0, i, 0 ) + #CRLF$
  Next 
It is very slow to use a lot of these Gadget commands to fill a string. ... It would be much faster, if you store all the data (which is also displayed in the ListIconGadget) in an appropriate array. If you fill the string from the array data the routine would be much faster!

cu, helpy
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Post by Polly »

Thanks helpy for your answer, but that doesn't solve the problem. The issue is that the main thread is able to do something apart from just waiting for an event - without slowing down the second thread terribly.

But thinking about your suggestion I found another solution. Instead of doing:

Code: Select all

While IsThread(t)
       ev=WindowEvent() 
       If Not ev: Delay(10) : EndIf
Wend
I just need to do:

Code: Select all

While IsThread(t)
       ev=WaitWindowEvent(10) 
      ; do something 
Wend
Then the main thread is at least able to do something or just wait for the termination of the thread after some event w/o slow-down.
Post Reply