Seite 2 von 2

Verfasst: 14.11.2004 19:06
von GPI
Was Access macht, mußt du MS fragen. Aber denkbar wäre es, das nur bsw. 10000 im Speicher sind und dann entsprechend geladen wird.

Verfasst: 16.11.2004 23:27
von Gerhard
Hallo,
habe mal meine Amateurfunkdatensätze (ca.16000) mit 15 Feldern
je Datensatz in das ListIconGadget eingelesen. Das dauert bei meinem
500 MHz Rechner (WinME) Intern 133 MHz Takt etwa 30 Sekunden.
Das ist für meinen Geschmack zu lang. Was mache ich falsch?
Ausserdem kann man nach dem Befüllen die Daten im Gadget nicht
mehr handlen. Beim Versuch eine Zeile herauszulöschen oder mehrere
herauszulöschen, stürzt das Gadget entweder ab, oder es werden nur
3 von 5 gelöscht, als ob das ListIconGadget bei der Datenmenge
überlastet ist. Oder mache ich was falsch?

Code: Alles auswählen

;ALLE QSOs des Logbuches ins Gadget einlesen:
While WindowEvent():Wend
;DisableGadget(#LIGadget_3,1)
For i=0 To 500000  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      While WindowEvent():Wend
      qsonr=Str(i+1)
      call=StringField(logbuch(i),1,"|")
      date=StringField(logbuch(i),2,"|")
      utc=StringField(logbuch(i),3,"|")
      dxcc=StringField(logbuch(i),4,"|")
      freq=StringField(logbuch(i),5,"|")
      mode=StringField(logbuch(i),6,"|")
      rsts=StringField(logbuch(i),7,"|")
      rstr=StringField(logbuch(i),8,"|")
      iota=StringField(logbuch(i),12,"|")
      locator=StringField(logbuch(i),13,"|")
      name=StringField(logbuch(i),10,"|")
      qth=StringField(logbuch(i),11,"|")
      manager=StringField(logbuch(i),9,"|")
      qsl=StringField(logbuch(i),15,"|")
      Select qsl
            Case "B":qsl="BURO"
            Case "D":qsl="DIRECT"
            Case "X":qsl="CFMD"
            Case "N":qsl="NO QSL"
      EndSelect
      zeile=qsonr+Chr(10)+call+Chr(10)+dxcc+Chr(10)+date+Chr(10)+utc+Chr(10)+RSet(freq,7," ")+Chr(10)+mode+Chr(10)+rsts+Chr(10)+rstr+Chr(10)+name+Chr(10)+qth+Chr(10)+iota+Chr(10)+locator+Chr(10)+manager+Chr(10)+qsl
      AddGadgetItem(#LIGadget_3,-1,zeile)
      ;While WindowEvent():Wend
      
Next i
While WindowEvent():Wend
;HideGadget(#LIGadget_3,0)
Weiss jemand noch mal Rat, oder muss ich eine grafische Lösung
für das anzeigen solcher Datenmengen selber programmieren?

Gruss Gerhard

Edit by NicTheQuick: Code-Tags gesetzt

Verfasst: 17.11.2004 14:29
von Danilo
Gerhard hat geschrieben:habe mal meine Amateurfunkdatensätze (ca.16000) mit 15
Feldern je Datensatz in das ListIconGadget eingelesen.
Das dauert bei meinem 500 MHz Rechner (WinME) Intern
133 MHz Takt etwa 30 Sekunden.
Das ist für meinen Geschmack zu lang.

Was mache ich falsch?
Es dauert einfach eine Weile, da Du die Strings zerlegen mußt.

Dein Code war ja nicht lauffähig, also habe ich das mal gemacht und mit 16.000 Datensätzen getestet.

Code: Alles auswählen

#LOG_COUNT  = 16000
#LIGadget_3 = 1

Dim logbuch.s(#LOG_COUNT)
For i = 0 To #LOG_COUNT
  A$ = Str(i+1)
  For a = 1 To 13
    A$+"|"+Hex(Random($FFFFFF))
  Next a

  Select Random(3)
    Case 0 : A$+"|B"
    Case 1 : A$+"|D"
    Case 2 : A$+"|X"
    Case 3 : A$+"|N"
  EndSelect
  logbuch(i)=A$
Next i


Procedure SetRedraw(hWnd,state)
  SendMessage_(hWnd,#WM_SETREDRAW,state,0)
EndProcedure

Procedure WndProc(hWnd,Msg,wParam,lParam)
  Select Msg
    Case #WM_SIZE
      ResizeGadget(1,5,5,(lParam&$FFFF)-10,((lParam>>16)&$FFFF)-10)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Fill()
  DisableDebugger
    time_start = ElapsedMilliseconds()
    SetRedraw(GadgetID(#LIGadget_3),0)

    For i=0 To #LOG_COUNT  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      While WindowEvent():Wend
      qsonr.s=Str(i+1)
      call.s=StringField(logbuch(i),1,"|")
      date.s=StringField(logbuch(i),2,"|")
      utc.s=StringField(logbuch(i),3,"|")
      dxcc.s=StringField(logbuch(i),4,"|")
      freq.s=StringField(logbuch(i),5,"|")
      mode.s=StringField(logbuch(i),6,"|")
      rsts.s=StringField(logbuch(i),7,"|")
      rstr.s=StringField(logbuch(i),8,"|")
      iota.s=StringField(logbuch(i),12,"|")
      locator.s=StringField(logbuch(i),13,"|")
      name.s=StringField(logbuch(i),10,"|")
      qth.s=StringField(logbuch(i),11,"|")
      manager.s=StringField(logbuch(i),9,"|")
      qsl.s=StringField(logbuch(i),15,"|")
      Select qsl
            Case "B":qsl="BURO"
            Case "D":qsl="DIRECT"
            Case "X":qsl="CFMD"
            Case "N":qsl="NO QSL"
      EndSelect
      zeile.s=qsonr+Chr(10)+call+Chr(10)+dxcc+Chr(10)+date+Chr(10)+utc+Chr(10)+RSet(freq,7," ")+Chr(10)+mode+Chr(10)+rsts+Chr(10)+rstr+Chr(10)+name+Chr(10)+qth+Chr(10)+iota+Chr(10)+locator+Chr(10)+manager+Chr(10)+qsl
      AddGadgetItem(#LIGadget_3,-1,zeile)
      ;While WindowEvent():Wend
     
    Next i


    time_end = ElapsedMilliseconds()-time_start
    SetRedraw(GadgetID(#LIGadget_3),1)
  EnableDebugger

  While WindowEvent():Wend

  MessageRequester("TIME",StrU(time_end,#LONG)+"ms")
EndProcedure

#Win0_flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

OpenWindow(0,0,0,600,400,#Win0_flags,"ListIconGadget")
  CreateGadgetList(WindowID())
  ListIconGadget(#LIGadget_3,5,5,590,390,"1",60,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    For i = 2 To 15
      AddGadgetColumn(#LIGadget_3,i-1,Str(i),60)
    Next i

  SetWindowCallback(@WndProc())

  While WindowEvent():Wend

  Fill()
  
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Bei mir dauert das einlesen der 16.000 Datensätze mit Deiner
StringField-Methode 2,968 Sekunden.

Dann habe ich es auf Pointer umgeschrieben, dann dauert
es hier 2,828 Sekunden:

Code: Alles auswählen

#LOG_COUNT  = 16000
#LIGadget_3 = 1

Dim index(15)

Dim logbuch.s(#LOG_COUNT)
For i = 0 To #LOG_COUNT
  A$ = Str(i+1)
  For a = 1 To 13
    A$+"|"+Hex(Random($FFFFFF))
  Next a

  Select Random(3)
    Case 0 : A$+"|B"
    Case 1 : A$+"|D"
    Case 2 : A$+"|X"
    Case 3 : A$+"|N"
  EndSelect
  logbuch(i)=A$
Next i

Procedure SetRedraw(hWnd,state)
  SendMessage_(hWnd,#WM_SETREDRAW,state,0)
EndProcedure

Procedure WndProc(hWnd,Msg,wParam,lParam)
  Select Msg
    Case #WM_SIZE
      ResizeGadget(1,5,5,(lParam&$FFFF)-10,((lParam>>16)&$FFFF)-10)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Fill()
  DisableDebugger
    time_start = ElapsedMilliseconds()
    SetRedraw(GadgetID(#LIGadget_3),0)

    Zeile$ = Space(10000)

    For i=0 To #LOG_COUNT  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      
      pos = 0
      For a = 1 To 15
        pos = FindString(logbuch(i),"|",pos+1)
        index(a)=pos
      Next a
      
      *p.BYTE = @Zeile$
      
      Restore order

      For a = 1 To 13
        Read x
        *word.BYTE = @logbuch(i)+index(x-1)
        *p\b = #LF : *p+1
        If x = 5
          count = 0
          While *word\b And *word\b <> '|'
            *word+1
            count+1
          Wend
          If count
            *word.BYTE = @logbuch(i)+index(x-1)
            x = 7-count
            If x>0
              For y=1 To x
                *p\b = 32: *p+1
              Next y
            EndIf
            While *word\b And *word\b <> '|'
              *p\b = *word\b
              *p+1 : *word+1
            Wend
          EndIf
        Else
          While *word\b And *word\b <> '|'
            *p\b = *word\b
            *p+1 : *word+1
          Wend
        EndIf
      Next a
      
      *p\b = #LF : *p+1
      
      *word.BYTE = @logbuch(i)+index(14)
      Select *word\b
        Case 'B' : PokeS(*p,"BURO")   : *p+4
        Case 'D' : PokeS(*p,"DIRECT") : *p+6
        Case 'X' : PokeS(*p,"CFMD")   : *p+4
        Case 'N' : PokeS(*p,"NO QSL") : *p+6
      EndSelect

      *p\b = 0
      AddGadgetItem(#LIGadget_3,-1,Str(i+1)+Zeile$)
     
    Next i


    time_end = ElapsedMilliseconds()-time_start
    SetRedraw(GadgetID(#LIGadget_3),1)
  EnableDebugger

  While WindowEvent():Wend

  MessageRequester("TIME",StrU(time_end,#LONG)+"ms")

DataSection
  order:
  Data.l 1,4,2,3,5,6,7,8,10,11,12,13,9,15
EndDataSection

EndProcedure

#Win0_flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

OpenWindow(0,0,0,800,400,#Win0_flags,"ListIconGadget")
  CreateGadgetList(WindowID())
  ListIconGadget(#LIGadget_3,5,5,790,390,"1",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    For i = 2 To 15
      AddGadgetColumn(#LIGadget_3,i-1,Str(i),70)
    Next i
    
  SetGadgetFont(#LIGadget_3,LoadFont(1,"Lucida Console",8))

  SetWindowCallback(@WndProc())

  While WindowEvent():Wend

  Fill()
  
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Als nächstes dann noch die Pointer durch Peek & Poke ersetzt,
was hier 2,829 Sekunden dauerte:

Code: Alles auswählen

#LOG_COUNT  = 16000
#LIGadget_3 = 1

Dim index(15)

Dim logbuch.s(#LOG_COUNT)
For i = 0 To #LOG_COUNT
  A$ = Str(i+1)
  For a = 1 To 13
    A$+"|"+Hex(Random($FFFFFF))
  Next a

  Select Random(3)
    Case 0 : A$+"|B"
    Case 1 : A$+"|D"
    Case 2 : A$+"|X"
    Case 3 : A$+"|N"
  EndSelect
  logbuch(i)=A$
Next i

Procedure SetRedraw(hWnd,state)
  SendMessage_(hWnd,#WM_SETREDRAW,state,0)
EndProcedure

Procedure WndProc(hWnd,Msg,wParam,lParam)
  Select Msg
    Case #WM_SIZE
      ResizeGadget(1,5,5,(lParam&$FFFF)-10,((lParam>>16)&$FFFF)-10)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Fill()
  DisableDebugger
    time_start = ElapsedMilliseconds()
    SetRedraw(GadgetID(#LIGadget_3),0)

    Zeile$ = Space(10000)

    For i=0 To #LOG_COUNT  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      
      pos = 0
      For a = 1 To 15
        pos = FindString(logbuch(i),"|",pos+1)
        index(a)=pos
      Next a
      
      *p = @Zeile$
      
      Restore order

      For a = 1 To 13
        Read x
        *word = @logbuch(i)+index(x-1)
        PokeB(*p,#LF) : *p+1
        If x = 5
          count = 0
          While PeekB(*word) And PeekB(*word) <> '|'
            *word+1
            count+1
          Wend
          If count
            *word = @logbuch(i)+index(x-1)
            x = 7-count
            If x>0
              For y=1 To x
                PokeB(*p,32) : *p+1
              Next y
            EndIf
            While PeekB(*word) And PeekB(*word) <> '|'
              PokeB(*p,PeekB(*word))
              *p+1 : *word+1
            Wend
          EndIf
        Else
          While PeekB(*word) And PeekB(*word) <> '|'
            PokeB(*p,PeekB(*word))
            *p+1 : *word+1
          Wend
        EndIf
      Next a
      
      PokeB(*p,#LF) : *p+1
      
      *word = @logbuch(i)+index(14)
      Select PeekB(*word)
        Case 'B' : PokeS(*p,"BURO")   : *p+4
        Case 'D' : PokeS(*p,"DIRECT") : *p+6
        Case 'X' : PokeS(*p,"CFMD")   : *p+4
        Case 'N' : PokeS(*p,"NO QSL") : *p+6
      EndSelect

      PokeB(*p,0)
      AddGadgetItem(#LIGadget_3,-1,Str(i+1)+Zeile$)
     
    Next i


    time_end = ElapsedMilliseconds()-time_start
    SetRedraw(GadgetID(#LIGadget_3),1)
  EnableDebugger

  While WindowEvent():Wend

  MessageRequester("TIME",StrU(time_end,#LONG)+"ms")

DataSection
  order:
  Data.l 1,4,2,3,5,6,7,8,10,11,12,13,9,15
EndDataSection

EndProcedure

#Win0_flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

OpenWindow(0,0,0,800,400,#Win0_flags,"ListIconGadget")
  CreateGadgetList(WindowID())
  ListIconGadget(#LIGadget_3,5,5,790,390,"1",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    For i = 2 To 15
      AddGadgetColumn(#LIGadget_3,i-1,Str(i),70)
    Next i
    
  SetGadgetFont(#LIGadget_3,LoadFont(1,"Lucida Console",8))

  SetWindowCallback(@WndProc())

  While WindowEvent():Wend

  Fill()
  
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Und als letztes noch eine Methode mit direktem PeekS(),
welches das StringField ersetzten soll:

Code: Alles auswählen

#LOG_COUNT  = 16000
#LIGadget_3 = 1

Dim index(15)

Dim logbuch.s(#LOG_COUNT)
For i = 0 To #LOG_COUNT
  A$ = Str(i+1)
  For a = 1 To 14
    A$+"|"+Hex(Random($FFFFFF))
  Next a

  Select Random(3)
    Case 0 : A$+"|B"
    Case 1 : A$+"|D"
    Case 2 : A$+"|X"
    Case 3 : A$+"|N"
  EndSelect
  logbuch(i)=A$
Next i

Procedure SetRedraw(hWnd,state)
  SendMessage_(hWnd,#WM_SETREDRAW,state,0)
EndProcedure

Procedure WndProc(hWnd,Msg,wParam,lParam)
  Select Msg
    Case #WM_SIZE
      ResizeGadget(1,5,5,(lParam&$FFFF)-10,((lParam>>16)&$FFFF)-10)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Fill()
  DisableDebugger
    time_start = ElapsedMilliseconds()
    SetRedraw(GadgetID(#LIGadget_3),0)

    For i=0 To #LOG_COUNT  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      
      pos = 0
      For a = 1 To 15
        pos = FindString(logbuch(i),"|",pos+1)
        index(a)=pos
      Next a

      Zeile$=""

      Restore order

      For a = 1 To 13
        Read x : x-1
        
        length = index(x+1)-index(x)
        Zeile$+#LF$
        If length
          If x = 4
            Zeile$+RSet( PeekS( @logbuch(i)+index(x), length-1), 7, " " )
          Else
            Zeile$+PeekS( @logbuch(i)+index(x), length-1)
          EndIf
        EndIf
      Next a
      
      Zeile$+#LF$
      
      *word.BYTE = @logbuch(i)+index(14)
      Select *word\b
        Case 'B' : Zeile$+"BURO"
        Case 'D' : Zeile$+"DIRECT"
        Case 'X' : Zeile$+"CFMD"
        Case 'N' : Zeile$+"NO QSL"
      EndSelect

      AddGadgetItem(#LIGadget_3,-1,Str(i+1)+Zeile$)
     
    Next i


    time_end = ElapsedMilliseconds()-time_start
    SetRedraw(GadgetID(#LIGadget_3),1)
  EnableDebugger

  While WindowEvent():Wend

  MessageRequester("TIME",StrU(time_end,#LONG)+"ms")

DataSection
  order:
  Data.l 1,4,2,3,5,6,7,8,10,11,12,13,9,15
EndDataSection

EndProcedure

#Win0_flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

OpenWindow(0,0,0,800,400,#Win0_flags,"ListIconGadget")
  CreateGadgetList(WindowID())
  ListIconGadget(#LIGadget_3,5,5,790,390,"1",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    For i = 2 To 15
      AddGadgetColumn(#LIGadget_3,i-1,Str(i),70)
    Next i
    
  SetGadgetFont(#LIGadget_3,LoadFont(1,"Lucida Console",8))

  SetWindowCallback(@WndProc())

  While WindowEvent():Wend

  Fill()
  
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Dabei dauerte es hier 2,984 Sekunden.

Endergebniss:

Code: Alles auswählen

Pointer:   2828 ms
Peek/Poke: 2829 ms
PeekS:     2984 ms
Original:  2968 ms
Wie man sehen kann ist es kein großer Unterschied. Gerade
mal 140 ms Unterschied.

Dann ersetzen wir mal noch das FindString in der Pointer-Version:

Code: Alles auswählen

#LOG_COUNT  = 16000
#LIGadget_3 = 1

Dim index(15)

Dim logbuch.s(#LOG_COUNT)
For i = 0 To #LOG_COUNT
  A$ = Str(i+1)
  For a = 1 To 13
    A$+"|"+Hex(Random($FFFFFF))
  Next a

  Select Random(3)
    Case 0 : A$+"|B"
    Case 1 : A$+"|D"
    Case 2 : A$+"|X"
    Case 3 : A$+"|N"
  EndSelect
  logbuch(i)=A$
Next i

Procedure SetRedraw(hWnd,state)
  SendMessage_(hWnd,#WM_SETREDRAW,state,0)
EndProcedure

Procedure WndProc(hWnd,Msg,wParam,lParam)
  Select Msg
    Case #WM_SIZE
      ResizeGadget(1,5,5,(lParam&$FFFF)-10,((lParam>>16)&$FFFF)-10)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Fill()
  DisableDebugger
    time_start = ElapsedMilliseconds()
    SetRedraw(GadgetID(#LIGadget_3),0)

    Zeile$ = Space(10000)

    For i=0 To #LOG_COUNT  ;es sind nur 16000(!)
      If logbuch(i)="":Break:EndIf
      
      x          = @logbuch(i)
      *word.BYTE = x
      For a = 1 To 15 : index(a)=0 : Next a

      a=1
      While *word\b And a<16
        If *word\b = '|'
          index(a) = *word - x + 1
          a+1
        EndIf
        *word+1
      Wend


      *p.BYTE = @Zeile$
      
      Restore order

      For a = 1 To 13
        Read x
        *word.BYTE = @logbuch(i)+index(x-1)
        *p\b = #LF : *p+1
        If x = 5
          count = 0
          While *word\b And *word\b <> '|'
            *word+1
            count+1
          Wend
          If count
            *word.BYTE = @logbuch(i)+index(x-1)
            x = 7-count
            If x>0
              For y=1 To x
                *p\b = 32: *p+1
              Next y
            EndIf
            While *word\b And *word\b <> '|'
              *p\b = *word\b
              *p+1 : *word+1
            Wend
          EndIf
        Else
          While *word\b And *word\b <> '|'
            *p\b = *word\b
            *p+1 : *word+1
          Wend
        EndIf
      Next a
      
      *p\b = #LF : *p+1
      
      *word.BYTE = @logbuch(i)+index(14)
      Select *word\b
        Case 'B' : PokeS(*p,"BURO")   : *p+4
        Case 'D' : PokeS(*p,"DIRECT") : *p+6
        Case 'X' : PokeS(*p,"CFMD")   : *p+4
        Case 'N' : PokeS(*p,"NO QSL") : *p+6
      EndSelect

      *p\b = 0
      AddGadgetItem(#LIGadget_3,-1,Str(i+1)+Zeile$)
     
    Next i


    time_end = ElapsedMilliseconds()-time_start
    SetRedraw(GadgetID(#LIGadget_3),1)
  EnableDebugger

  While WindowEvent():Wend

  MessageRequester("TIME",StrU(time_end,#LONG)+"ms")

DataSection
  order:
  Data.l 1,4,2,3,5,6,7,8,10,11,12,13,9,15
EndDataSection

EndProcedure

#Win0_flags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget

OpenWindow(0,0,0,800,400,#Win0_flags,"ListIconGadget")
  CreateGadgetList(WindowID())
  ListIconGadget(#LIGadget_3,5,5,790,390,"1",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    For i = 2 To 15
      AddGadgetColumn(#LIGadget_3,i-1,Str(i),70)
    Next i
    
  SetGadgetFont(#LIGadget_3,LoadFont(1,"Lucida Console",8))

  SetWindowCallback(@WndProc())

  While WindowEvent():Wend

  Fill()
  
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Und nun:

Code: Alles auswählen

Pointer Neu: 2719 ms
Pointer:     2828 ms
Peek/Poke:   2829 ms
PeekS:       2984 ms
Original:    2968 ms
Also insgesamt 249 ms vom Original herausgeholt. Eine viertel
Sekunde, bei 16.000 Einträgen. Naja.

Natürlich könnte man jetzt noch Dies und Das weiter versuchen
zu optimieren, aber letztendlich ist es nicht so ein großer
Unterschied. Es ist im Millisekundenbereich bei 16.000 Einträgen.

Das zerlegen/ordnen ist also schnell genug und macht nicht
viel aus.
Was das meiste ausmachen wird: Das Gadget muß neuen
Speicher reservieren, wenn Du eine Zeile hinzufügst.
Und der String wird dann halt in diesen ListIcon-Speicher
kopiert, da das ListView diese Daten ja braucht.

Du sprichst aber gleich von 30 Sekunden für 16.000 Einträge,
was mich etwas wundert.
Probier mal die obigen Versionen, ob die auch alle um die
30 Sekunden bei Dir brauchen.
Sollte auch auf Deinem Rechner unter 10 Sekunden bleiben.