Sortierprogramm fast fertig. Noch ein Fehler...
-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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.
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.
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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.SebastianJu2 hat geschrieben:Scheint also wie wenn Listen zumindest nicht langsamer sind. Viel mehr kann der Test wohl auch nicht aussagen.
"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
-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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...
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...

-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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)"
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
Re: Sortierprogramm fast fertig. Noch ein Fehler...
Ruhe bewahren, und einen eisgekühlten BOMmerlunder trinken.SebastianJu2 hat geschrieben:Was tut man eigentlich wenn das BOM nicht am Anfang steht?

-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
Aber nur einen... sonst wars das mit der Codingfähigkeit fürs erste... 

Re: Sortierprogramm fast fertig. Noch ein Fehler...
@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
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²
-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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...
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...
-
- Beiträge: 180
- Registriert: 24.09.2010 10:39
Re: Sortierprogramm fast fertig. Noch ein Fehler...
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:
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.

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:
Und der Code: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
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