Sortierprogramm fast fertig. Noch ein Fehler...

Anfängerfragen zum Programmieren mit PureBasic.
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Ich habs jetzt noch mal umgeschrieben auf Listen. Vorher habe ich Zeiten aufgeschrieben. Ich habe immer 4 Millisekundenwerte ausgeben lassen. Zeilen einlesen, Sortieren und Schreiben. Dann noch die Gesamtzeit.
Zum testen wurde eine Text-Datei mit URLs benutzt. 213.141 URLs. Und pro Codeversion habe ich 3 Durchläufe gemacht.

Messung mit dem Code den ich gepostet habe:
390-249-156-795
390-281-140-811
390-250-171-811

Durchschnitt:
390-260-156-806

Messung mit Arrays bei denen Redim nur alle Tausend Zeilen für 1000 neue Arraybestandteile gemacht wurde. Danach ein Redim auf die tatsächliche Anzahl:
328-234-124-686
374-234-156-764
374-234-140-748

Durchschnitt:
359-234-140-733

Mit Listen. Praktisch genauso benutzt wie der erste Versuch mit den Arrays
281-234-156-671
312-219-171-702
374-265-156-795

Durchschnitt:
323-239-161-723

Scheint also wie wenn Listen zumindest nicht langsamer sind. Viel mehr kann der Test wohl auch nicht aussagen.
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von c4s »

SebastianJu2 hat geschrieben:Scheint also wie wenn Listen zumindest nicht langsamer sind. Viel mehr kann der Test wohl auch nicht aussagen.
Nicht vergessen, dass der Debugger bei Geschwindigkeitstests aus sein muss, um brauchbare Ergebnisse zu liefern. Solltest du die Demo-Version haben, funktioniert dieses glaube ich nicht.
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Stimmt... das bringt noch mal etwas Geschwindigkeit.

Die jetzige Version hat nun durschnittlich 604ms gebraucht und vorher waren es 723ms.

Gibt es jetzt noch Optimierungsmöglichkeiten? Beispielsweise beim lesen und Schreiben in die Dateien? Wäre es schneller wenn man vielleicht immer 100 Zeilen auf einmal schreibt oder so? Was ist mit Threads? Im Moment benutzt das Programm nur einen Prozessorkern. Ansonsten wäre wahrscheinlich nicht mehr viel zu optimieren außer man will Assembler usw nutzen.

Also so wie PB rüberkommt ist es eine gute Sache. Fenster und alles sind einfach zu bauen. Ich hatte mich vorher mal an C++ versucht aber das ist doch echt kryptisch und 10 mal mehr Arbeit. Ich hoffe mal nur dass die Einfachheit von PB nicht im Detail später beschränkt ist... mal schauen... :)
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Hier mal das aktuelle Ergebnis. Ich habe jetzt die Zeichenkodierung mit reingenommen. Bin mir aber nicht sicher ob das so implementiert wird. Was tut man eigentlich wenn das BOM nicht am Anfang steht?

Wenn man eine Variable gegen mehrere Werte vergleichen will gibt es dann einen Befehl wie "in"? Also "var in (3,113,2)"

Code: Alles auswählen

Procedure Msg(Msg$,Type.l = 0) ;If Type isnt set the Message is a Errormessage
  If Type = 0 : Type$ = "Error" : Else : Type$ = "Message" : EndIf
  MessageRequester(Type$, Type$+": " + Msg$, 0)
  If Type = 0 : End : EndIf
EndProcedure

Procedure ChkCreated(Handle,Type$)
  If Handle = 0 : Msg("Couldnt create " + Type$) : EndIf
EndProcedure

MainWindowHandle=OpenWindow(#PB_Any, 0, 0, 600, 180, "SortIt", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)
ChkCreated(MainWindowHandle,"Window")

SourceButtonHandle = ButtonGadget(#PB_Any, 10, 10, 110, 25, "Choose Sourcefile")
ChkCreated(SourceButtonHandle,"Button")

TargetButtonHandle = ButtonGadget(#PB_Any, 10, 45, 110, 25, "Choose Targetfile")
ChkCreated(TargetButtonHandle,"Button")

SourceStringHandle = StringGadget(#PB_Any, 140, 10, 445, 25, "")
ChkCreated(SourceStringHandle,"Inputbox")

TargetStringHandle = StringGadget(#PB_Any, 140, 45, 445, 25, "")
ChkCreated(TargetStringHandle,"Inputbox")

LogEditorHandle = EditorGadget(#PB_Any, 10,  80, 250, 90, #PB_Editor_ReadOnly)
ChkCreated(LogEditorHandle,"Logtextarea")

SortAscOptionHandle = OptionGadget(#PB_Any, 270, 80, 100, 20, "Sort Ascending")
ChkCreated(SortAscOptionHandle,"Option")

SortDescOptionHandle = OptionGadget(#PB_Any, 270, 100, 100, 20, "Sort Descending")
ChkCreated(SortDescOptionHandle,"Option")

SetGadgetState(SortAscOptionHandle, 1)

SortNoCaseCheckboxHandle = CheckBoxGadget(#PB_Any, 380, 80, 120, 20, "Sort NoCase")
ChkCreated(SortNoCaseCheckboxHandle,"Checkbox")

DeleteBlankRowsCheckboxHandle = CheckBoxGadget(#PB_Any, 380, 100, 120, 20, "Delete Blank Rows")
ChkCreated(DeleteBlankRowsCheckboxHandle,"Checkbox")

StartButtonHandle = ButtonGadget(#PB_Any, 505, 80, 80, 50, "START")
ChkCreated(StartButtonHandle,"Button")

Repeat
  EventID = WaitWindowEvent()
  If EventWindow() = MainWindowHandle And EventID = #PB_Event_Gadget
    If EventGadget() = SourceButtonHandle
      File$ = OpenFileRequester("Please choose the file to read from", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the source",1) : File$ = "" : EndIf
        SetGadgetText(SourceStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = TargetButtonHandle
      File$ = OpenFileRequester("Please choose the file to write to", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the target",1) : File$ = "" : EndIf
        SetGadgetText(TargetStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = StartButtonHandle
      ;Stringgadgets unbeschreibbar für User machen?
      Repeat  
        If FileSize(GetGadgetText(SourceStringHandle)) = -1 : Msg("Sourcefile doesnt exist",1) : SetGadgetText(SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(SourceStringHandle)) = -2 : Msg("Sourcefile cant be a directory",1) : SetGadgetText(SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(TargetStringHandle)) = -2 : Msg("Targetfile cant be a directory",1) : SetGadgetText(TargetStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(TargetStringHandle)) >= 0
          Result.l = MessageRequester("Request", "Targetfile already exists. Overwrite?", #PB_MessageRequester_YesNo)
          If Result = #PB_MessageRequester_No : Break : EndIf
        EndIf
        
        SetGadgetText(LogEditorHandle, "")
        
        ReadFileHandle = ReadFile(#PB_Any, GetGadgetText(SourceStringHandle))
        WriteFileHandle = CreateFile(#PB_Any, GetGadgetText(TargetStringHandle))
        If Not ReadFileHandle : Msg("Couldnt open Sourcefile") : Break : EndIf
        If Not WriteFileHandle : Msg("Couldnt open Targetfile") : Break : EndIf
        
        StringCoding = ReadStringFormat(ReadFileHandle)
        If Not (StringCoding = #PB_Ascii Or StringCoding = #PB_UTF8 Or StringCoding = #PB_Unicode)
          Msg("Found unknown StringCoding. Cant sort it.",1)
          Break
        EndIf 
        
        StartTime = ElapsedMilliseconds()
        FirstStartTime = StartTime
        
;         Dim SourceFileContent$(1000)
        NewList SourceFileContent$()

        x.l=0
        While Eof(ReadFileHandle) = 0
          AddElement(SourceFileContent$())
;           If x % 1000 = 0 : ReDim SourceFileContent$(x + 1000) : EndIf
          SourceFileContent$() = ReadString(ReadFileHandle)
          x+1
        Wend
        CloseFile(ReadFileHandle)
        
;         ReDim SourceFileContent$(x)
        
        SetGadgetText(LogEditorHandle, Str(x) + " Lines read from Sourcefile in " + Str(ElapsedMilliseconds() - StartTime) + " ms")
        
        Flags.l = 0 : DelBlank.l = 0
        If GetGadgetState(SortDescOptionHandle) = 1 : Flags+1 : EndIf
        If GetGadgetState(SortNoCaseCheckboxHandle) = 1 : Flags+2 : EndIf
        If GetGadgetState(DeleteBlankRowsCheckboxHandle) = 1 : DelBlank = 1 : EndIf
        
        StartTime = ElapsedMilliseconds()
        
        SortList(SourceFileContent$(), Flags)
;         SortArray(SourceFileContent$(), Flags)
        
        SetGadgetText(LogEditorHandle, GetGadgetText(LogEditorHandle) + #CRLF$ + Str(x) + " Lines sorted in " + Str(ElapsedMilliseconds() - StartTime) + " ms")
        
        WriteStringFormat(WriteFileHandle,StringCoding)
        
        StartTime = ElapsedMilliseconds()
        
        ForEach SourceFileContent$()
          If DelBlank = 1 And SourceFileContent$() = "" : x-1 : Continue : EndIf
          WriteStringN(WriteFileHandle, SourceFileContent$(),StringCoding)
        Next
        
;         For y = 0 To ArraySize(SourceFileContent$())
;           If DelBlank = 1 And SourceFileContent$(y) = "" : x-1 : Continue : EndIf
;           WriteStringN(WriteFileHandle, SourceFileContent$(y)) ;Ascii, UF8 usw beachten?
;         Next
        CloseFile(WriteFileHandle)
        
        SetGadgetText(LogEditorHandle, GetGadgetText(LogEditorHandle) + #CRLF$ + Str(x) + " Lines written in " + Str(ElapsedMilliseconds() - StartTime) + " ms")
        SetGadgetText(LogEditorHandle, GetGadgetText(LogEditorHandle) + #CRLF$ + "All done in: " + Str(ElapsedMilliseconds() - FirstStartTime) + " ms")
        
      Until #True
    EndIf
  EndIf
Until EventID = #PB_Event_CloseWindow
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von Nino »

SebastianJu2 hat geschrieben:Was tut man eigentlich wenn das BOM nicht am Anfang steht?
Ruhe bewahren, und einen eisgekühlten BOMmerlunder trinken. :mrgreen: SCNR
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Aber nur einen... sonst wars das mit der Codingfähigkeit fürs erste... ;)
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von Kiffi »

@SebastianJu2: Noch ein Wort zu Deinem ChkCreated()

Ich persönlich bin der Meinung, dass man davon ausgehen kann,
dass Gadgets immer erstellt werden können, wenn das dazugehörige
OpenWindow() geklappt hat. Eine gesonderte Prüfung halte ich deswegen
in diesem Zusammenhang für überflüssig (zumal Du im Fall eines Fehlers
ja auch keine Konsequenzen ziehst; ist Dein Programm noch 'brauchbar',
wenn TargetStringHandle 0 ist? ;-))

Und wenn OpenWindow() fehlschlägt, funktioniert dann überhaupt noch
der MessageRequester, welcher doch auch ein Fenster ist? Wir hatten
diesbezüglich vor einiger Zeit mal ne Diskussion, aber so richtig auf einen
grünen Zweig gekommen sind wir dabei nicht.

Nur mal so als Gedankenanregung...

Grüße ... Kiffi
a²+b²=mc²
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Stimmt... für den Fall hab ich das End vergessen...

Ich nehm die Checks dann mal raus und nutze sie nur beim Fenster.

Bei MessageRequester weiß ich nicht. Wenn es nicht geht kommt eventuell eine Fehlermeldung vom System? Und wenn das nicht geht ist fraglich ob Window überhaupt gestartet werden kann. Falls keine Fehlermeldug kommt sieht man kein Fenster und kein Fehlermeldungsfenster. Es passiert einfach nichts bei Klick... Eventuell sollte man noch ein Log einbauen für solche Fälle...
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Mir scheint das Programm ist fertig... :) (Es kann nichts weltbewegendes aber als Übung wars gut denke ich.) Ich habe alle Funktionen getestet und keine Fehler gefunden. Ich poste den Code mal hier und vielleicht hat jemand noch Verbesserungsvorschläge oder findet Fehler.

Das Programm kann:
* Texte in Ascii, Unicode und UTF-8 einlesen, die Zeilenreihenfolge bearbeiten und wieder in eine Datei ausgeben
* Beim Bearbeiten kann es die Zeilen Sortieren (Aufsteigend, Aufsteigend NoCase, Absteigend, Absteigend NoCase, Zufällig anordnen oder die Reihenfolge nicht verändern)
* Dazu und in Kombination kann es Zeilen löschen (Doppelte, Doppelte NoCase oder keine doppelten Zeilen Löschen)
* Dazu noch in Kombination die Option leere Zeilen zu entfernen
* Auf Geschwindigkeit optimiert soweit ich Möglichkeiten dazu gefunden habe
* Speedtestmodes mit 20 Durchläufen. Ein und auschaltbar wenn die Maus unten links im Formular in einem 20 Pixel hohen und breiten Bereich steht und man speedmode eingibt. Genauso ist es wieder ausschaltbar.

Hier mal der Inhalt einer Textdatei die ich zum Testen genommenn habe:
a
A
a



b
B
b
B
b

l
l
L
L
L
l
l
aa
aA
Aa
aa
AA
AA
aa
aA
Aa
aa
AA
aA
aA
aA
Aa
Und der Code:

Code: Alles auswählen

EnableExplicit

#LoopsSpeedmodeMax =20

Structure TimerLog
  All.i
  ReadSource.i
  Delete.i
  Sort.i
  Write.i
EndStructure

Structure DataList
  OrigPos.i
  DelRow.a
  DataRow$
EndStructure

Global.i *LogEditorHandle, LastScrollTime
Define.TimerLog AllStat
Define.i *MainWindowHandle, *SourceButtonHandle, *SourceStringHandle, *TargetButtonHandle, *TargetStringHandle
Define.i *SortTextHandle, *SortComboBoxHandle, *DeleteTextHandle, *DeleteBlankRowsCheckboxHandle, *StartButtonHandle
Define.i *DeleteComboBoxHandle, *HiddenModeTextHandle, *ReadFileHandle, *WriteFileHandle, *RegexHandle
Define.i LoopsSpeedmode, Lines, MouseX, MouseY, x, EventID, StartTime, FirstStartTime, SpeedtestStartTime
Define.s HiddenModeKeys$, File$, LastRowContent$, Clipboard$
Define.a Speedmode, Result, StringCoding, SortStyle, DeleteStyle, DeleteBlankRows, Flags, DelBlank

Procedure Msg(Msg$,Type.a = 0)
Define.s Type$
  If Not Type: Type$ = "Error" : Else : Type$ = "Message" : EndIf
  MessageRequester(Type$, Type$+": " + Msg$, 0)
  If Not Type : End : EndIf
EndProcedure

Procedure ChkCreated(*Handle.i, Type$, Action$ = "create")
  If Not *Handle : Msg("Couldnt " + Action$ + " " + Type$) : End : EndIf
EndProcedure

Procedure WriteLog(LogEntry$, EndofLog.a = 0)
  AddGadgetItem(*LogEditorHandle, -1, LogEntry$)
  If (ElapsedMilliseconds() - LastScrollTime) > 100 Or EndofLog
    SendMessage_(GadgetID(*LogEditorHandle),#EM_SCROLL,#SB_BOTTOM,0)
    LastScrollTime = ElapsedMilliseconds()
  EndIf
EndProcedure

Procedure In(ValueToCheck.i,ValueString$)
Define.i ValueCount, x
  ValueCount = CountString(ValueString$,",") + 1
  For x = 1 To ValueCount
    If Val(StringField(ValueString$, x, ",")) = ValueToCheck
      ProcedureReturn 1
    EndIf
  Next
  ProcedureReturn 0
EndProcedure

Macro Float(Long)
  ((Long)*1.0)
EndMacro

;Creating Window and Gadgets
;-----------------------
*MainWindowHandle=OpenWindow(#PB_Any, 0, 0, 661, 180, "SortIt", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)
ChkCreated(*MainWindowHandle,"Window")
*SourceButtonHandle = ButtonGadget(#PB_Any, 10, 10, 110, 25, "Choose Sourcefile")
*TargetButtonHandle = ButtonGadget(#PB_Any, 10, 45, 110, 25, "Choose Targetfile")
*SourceStringHandle = StringGadget(#PB_Any, 140, 10, 510, 25, "")
*TargetStringHandle = StringGadget(#PB_Any, 140, 45, 510, 25, "")
*LogEditorHandle = EditorGadget(#PB_Any, 10,  80, 250, 90, #PB_Editor_ReadOnly)

*SortTextHandle = TextGadget(#PB_Any, 270, 83, 80, 20, "Sort-Options:")
*SortComboBoxHandle = ComboBoxGadget(#PB_Any, 350, 80, 200, 20)
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Ascending Case Sensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Ascending Case Insensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Descending Case Sensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Descending Case Insensitive")
AddGadgetItem(*SortComboBoxHandle, -1, "Sort Randomly")
AddGadgetItem(*SortComboBoxHandle, -1, "No Change in Order")
SetGadgetState(*SortComboBoxHandle, 0)

*DeleteTextHandle = TextGadget(#PB_Any, 270, 113, 80, 30, "Delete-Options:")
*DeleteComboBoxHandle = ComboBoxGadget(#PB_Any, 350, 110, 200, 20)
AddGadgetItem(*DeleteComboBoxHandle, -1, "Delete Duplicate Rows Case Sensitive")
AddGadgetItem(*DeleteComboBoxHandle, -1, "Delete Duplicate Rows Case Insensitive")
AddGadgetItem(*DeleteComboBoxHandle, -1, "Dont Delete Duplicate Rows")
SetGadgetState(*DeleteComboBoxHandle, 2)
*DeleteBlankRowsCheckboxHandle = CheckBoxGadget(#PB_Any, 350, 137, 200, 20, "Delete Blank Rows")

*StartButtonHandle = ButtonGadget(#PB_Any, 570, 80, 80, 50, "START")
*HiddenModeTextHandle = TextGadget(#PB_Any, 570, 140, 80, 20, "")
SetGadgetColor(*HiddenModeTextHandle, #PB_Gadget_FrontColor, $0000FF)

Repeat
  EventID = WaitWindowEvent()
  
  ;Switch for en- and disabling Speedtestmode
  ;-----------------------
  If EventID = #WM_KEYDOWN
    MouseX = WindowMouseX(*MainWindowHandle)
    MouseY = WindowMouseY(*MainWindowHandle)
    If MouseX >= 0 And MouseX <=20 And MouseY >= 160 And MouseY <= 180
      HiddenModeKeys$ = Right(HiddenModeKeys$ + Chr(EventwParam()), 9)
      If HiddenModeKeys$ = "SPEEDMODE"
        If GetGadgetText(*HiddenModeTextHandle) = ""
          SetGadgetText(*HiddenModeTextHandle, "Speedtestmode")
          Speedmode = 1
        Else
          SetGadgetText(*HiddenModeTextHandle, "")
          Speedmode = 0
        EndIf
      EndIf
    Else
      HiddenModeKeys$ = ""
    EndIf
  EndIf
 
  If EventWindow() = *MainWindowHandle And EventID = #PB_Event_Gadget
    If EventGadget() = *SourceButtonHandle
      File$ = OpenFileRequester("Please choose the file to read from", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the source",1) : File$ = "" : EndIf
        SetGadgetText(*SourceStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = *TargetButtonHandle
      File$ = OpenFileRequester("Please choose the file to write to", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the target",1) : File$ = "" : EndIf
        SetGadgetText(*TargetStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = *StartButtonHandle
      Repeat
        If FileSize(GetGadgetText(*SourceStringHandle)) = -1 : Msg("Sourcefile doesnt exist",1) : SetGadgetText(*SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(*SourceStringHandle)) = -2 : Msg("Sourcefile cant be a directory",1) : SetGadgetText(*SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(*TargetStringHandle)) = -2 : Msg("Targetfile cant be a directory",1) : SetGadgetText(*TargetStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(*TargetStringHandle)) >= 0 And Not Speedmode 
          Result = MessageRequester("Request", "Targetfile already exists. Overwrite?", #PB_MessageRequester_YesNo)
          If Result = #PB_MessageRequester_No : Break : EndIf
        EndIf
        
        SetGadgetText(*LogEditorHandle, "")
        NewList TimerLogList.TimerLog()
        LoopsSpeedmode = 0
        SpeedtestStartTime = ElapsedMilliseconds()
        Repeat
          LoopsSpeedmode + 1
          *ReadFileHandle = ReadFile(#PB_Any, GetGadgetText(*SourceStringHandle))
          *WriteFileHandle = CreateFile(#PB_Any, GetGadgetText(*TargetStringHandle))
          If Not *ReadFileHandle : Msg("Couldnt open Sourcefile") : Break : EndIf
          If Not *WriteFileHandle : Msg("Couldnt open Targetfile") : Break : EndIf
          
          StringCoding = ReadStringFormat(*ReadFileHandle)
          If Not (StringCoding = #PB_Ascii Or StringCoding = #PB_UTF8 Or StringCoding = #PB_Unicode)
            Msg("Found unknown StringCoding. Cant work with it.",1)
            Break
          EndIf 
          
          AddElement(TimerLogList())
          StartTime = ElapsedMilliseconds()
          FirstStartTime = StartTime
          
          SortStyle = GetGadgetState(*SortComboBoxHandle)
          DeleteStyle = GetGadgetState(*DeleteComboBoxHandle)
          DeleteBlankRows = GetGadgetState(*DeleteBlankRowsCheckboxHandle)
          
          ;Read in File Data
          ;-----------------------
          NewList DataList.DataList()
          If SortStyle = 4 : Dim *SourceFileContentListPointerArray(1000) : EndIf
          
          Lines = 0
          While Eof(*ReadFileHandle) = 0
            If SortStyle = 4
              If Lines % 1000 = 0
                ReDim *SourceFileContentListPointerArray(Lines + 1000)
              EndIf
              *SourceFileContentListPointerArray(Lines) = AddElement(DataList())
            Else
              AddElement(DataList())
            EndIf
            DataList()\DataRow$ = ReadString(*ReadFileHandle,StringCoding)
            DataList()\OrigPos = Lines
            Lines + 1
          Wend
          If SortStyle = 4 : ReDim *SourceFileContentListPointerArray(Lines - 1) : EndIf
          CloseFile(*ReadFileHandle)
          
          TimerLogList()\Readsource = ElapsedMilliseconds() - StartTime
          Select StringCoding
            Case #PB_Ascii
              Clipboard$ = "Ascii"
            Case #PB_UTF8
              Clipboard$ = "UTF8"
            Case #PB_Unicode
              Clipboard$ = "Unicode"
          EndSelect
          WriteLog(Str(Lines) + " Lines " + Clipboard$ + "-Data read in " + Str(TimerLogList()\Readsource) + " ms (" + StrF(Float(TimerLogList()\Readsource) / 1000,3) + " s)")
          
          StartTime = ElapsedMilliseconds()
          
          ;First Handle the deletions
          ;-----------------------
          If DeleteStyle = 0 Or DeleteStyle = 1.
            If DeleteStyle = 1 : Flags = 2 : Else : Flags = 0 : EndIf 
            SortStructuredList(DataList(), Flags ,OffsetOf(DataList\DataRow$), #PB_Sort_String)
            Lines = 0
            LastRowContent$ = "@@@@@####*****@@@@"
            ForEach DataList()
              Lines + 1
              If DataList()\DataRow$ = "" Or LastRowContent$ = ""
                If DeleteBlankRows And DataList()\DataRow$ = ""
                  Lines - 1
                EndIf
                LastRowContent$ = DataList()\DataRow$
                Continue
              EndIf
              If DeleteStyle = 0 And DataList()\DataRow$ = LastRowContent$
                DataList()\DelRow = 1
                Lines - 1
              EndIf
              If DeleteStyle = 1 And LCase(DataList()\DataRow$) = LCase(LastRowContent$)
                DataList()\DelRow = 1
                Lines - 1
              EndIf
              LastRowContent$ = DataList()\DataRow$
            Next
          EndIf
          
          If DeleteStyle = 2 And DeleteBlankRows
            Lines = 0
            ForEach DataList()
              Lines + 1
              If DataList()\DataRow$ = "" : Lines - 1 : EndIf
            Next
          EndIf
          
          TimerLogList()\Delete = ElapsedMilliseconds() - StartTime
          WriteLog(Str(Lines) + " Lines left after Deletion in " + Str(TimerLogList()\Delete) + " ms (" + StrF(Float(TimerLogList()\Delete) / 1000,3) + " s)")
          
          StartTime = ElapsedMilliseconds()
          
          ;Sorting
          ;-----------------------
          Select SortStyle
            Case 0, 1, 2, 3
              Flags = 0
              Select SortStyle
                Case 1
                  Flags = 2
                Case 2
                  Flags = 1
                Case 3
                  Flags = 3
              EndSelect
              If Not ((SortStyle = 1 And DeleteStyle = 1) Or (SortStyle = 0 And DeleteStyle = 0)) ;Sort only needed when not already done
                SortStructuredList(DataList(), Flags, OffsetOf(DataList\DataRow$), #PB_Sort_String)
              EndIf
          EndSelect
            
          ;Randomize
          ;-----------------------
          If SortStyle = 4
            For x = ArraySize(*SourceFileContentListPointerArray()) - 1 To 1 Step -1
              ;Must be random(x) and not x-1 otherwise the last element couldnt swap with itself and remain at the last position after shuffling
              SwapElements(DataList(), *SourceFileContentListPointerArray(x), *SourceFileContentListPointerArray(Random(x)))
            Next
          EndIf
          
          ;Bring back the Row-Order from before when User didnt want to sort the list in any way
          ;-----------------------
          If In(DeleteStyle,"0,1") And SortStyle = 5
            SortStructuredList(DataList(), #PB_Sort_Ascending, OffsetOf(DataList\OrigPos), #PB_Sort_Integer)
          EndIf
          
          TimerLogList()\Sort = ElapsedMilliseconds() - StartTime
          WriteLog(Str(Lines) + " Lines are sorted in " + Str(TimerLogList()\Sort) + " ms (" + StrF(Float(TimerLogList()\Sort) / 1000,3) + " s)")
          
          WriteStringFormat(*WriteFileHandle,StringCoding)
          
          Lines = 0
          ForEach DataList()
            If (DeleteBlankRows And DataList()\DataRow$ = "") Or DataList()\DelRow : Continue : EndIf
            Lines + 1
            WriteStringN(*WriteFileHandle, DataList()\DataRow$,StringCoding)
          Next
          
          CloseFile(*WriteFileHandle)
          
          TimerLogList()\Write = ElapsedMilliseconds() - StartTime
          WriteLog(Str(Lines) + " Lines written in " + Str(TimerLogList()\Write) + " ms (" + StrF(Float(TimerLogList()\Write) / 1000,3) + " s)")
          TimerLogList()\All = ElapsedMilliseconds() - FirstStartTime
          If Speedmode
            WriteLog("Round " + Str(LoopsSpeedmode) + " of " + Str(#LoopsSpeedmodeMax) + " completely done in: " + Str(TimerLogList()\All) + " ms (" + StrF(Float(TimerLogList()\All) / 1000,3) + " s)" + #CRLF$ + "-----------------------")
          Else
            WriteLog("All done in: " + Str(TimerLogList()\All) + " ms (" + StrF(Float(TimerLogList()\All) / 1000,3) + " s)")
          EndIf
          If Speedmode And LoopsSpeedmode = #LoopsSpeedmodeMax
            ClearStructure(@AllStat, TimerLog)
            ForEach TimerLogList()
              AllStat\All + TimerLogList()\All
              AllStat\ReadSource + TimerLogList()\ReadSource
              AllStat\Delete + TimerLogList()\Delete
              AllStat\Sort + TimerLogList()\Sort
              AllStat\Write + TimerLogList()\Write
            Next
            AllStat\All / #LoopsSpeedmodeMax
            AllStat\ReadSource / #LoopsSpeedmodeMax
            AllStat\Delete / #LoopsSpeedmodeMax
            AllStat\Sort / #LoopsSpeedmodeMax
            AllStat\Write / #LoopsSpeedmodeMax
            WriteLog("Speedtest-Result: (" + Str(#LoopsSpeedmodeMax) + " Loops): " + #CRLF$ + "Read: " + Str(AllStat\ReadSource) + " ms on average" + #CRLF$ + "Delete: " + Str(AllStat\Delete) + " ms on average" + #CRLF$ + "Sort: " + Str(AllStat\Sort) + " ms on average" + #CRLF$ + "Write: " + Str(AllStat\Write) + " ms on average" + #CRLF$ + "Rounds done in: " + Str(AllStat\All) + " ms on average" + #CRLF$ + "Whole Speedtest took: " + Str(ElapsedMilliseconds() - SpeedtestStartTime) + " ms",1)
          EndIf
        Until LoopsSpeedmode = #LoopsSpeedmodeMax Or Not Speedmode
      Until #True
    EndIf
  EndIf
Until EventID = #PB_Event_CloseWindow
Eine Verbesserungsmöglichkeit wäre noch eine Erwähnung von Nic, das Modell Model View Controller. Da muss ich aber erstmal schauen wie man das praktisch umsetzt.
Antworten