Stringvergleich
- NicTheQuick
- Ein Admin
- Beiträge: 8807
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Stringvergleich
Genau. Es kommt halt immer drauf an, was man will. Die Vergleichroutine selbst ist natürlich das schnellste, was geht.
Es gibt es aber auch die Möglichkeit eine temporäre sortierte Liste zu erstellen ohne die Ursprungslisten zu ändern. Oder das ganze in ein temporäres Array zu betten. Vielleicht ist das auch nochmal schneller als LinkedLists.
Es gibt es aber auch die Möglichkeit eine temporäre sortierte Liste zu erstellen ohne die Ursprungslisten zu ändern. Oder das ganze in ein temporäres Array zu betten. Vielleicht ist das auch nochmal schneller als LinkedLists.
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Leider verstehe ich den Code nicht.
Nun habe ich mal mit "Map" gearbeitet. Bei 10000 Daten in Datei 1 und 10000 in Datei 2 dauert ein Durchlauf kann 170ms.
Win7
Netbook; 1,7 GHZ; MonoCore
Nun habe ich mal mit "Map" gearbeitet. Bei 10000 Daten in Datei 1 und 10000 in Datei 2 dauert ein Durchlauf kann 170ms.
Win7
Netbook; 1,7 GHZ; MonoCore
Code: Alles auswählen
NewList Liste1.s()
NewList Liste2.s()
NewList Liste3.s()
NewList Liste4.s()
NewList DateiName.s()
NewMap Datei1.s()
NewMap Datei2.s()
If OpenWindow(0, 100, 150, 500, 300, "Dateivergleich")
If CreateMenu(0, WindowID(0))
MenuTitle("Datei")
MenuItem( 5, "Datei_1")
MenuItem( 6, "Datei_2")
MenuBar()
MenuItem( 7, "&Quit")
MenuTitle("Vergleich")
MenuItem( 8, "Dateivergleich")
MenuTitle("?")
MenuItem(11, "About")
EndIf
; This is the 'event loop'. All the user actions are processed here.
; It's very easy to understand: when an action occurs, the Event
; isn't 0 and we just have to see what have happened...
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu
Select EventMenu()
Case 5:
FileName1$ = OpenFileRequester("Wählen die erste der beiden zu vergleichenden Dateien aus", "F:\Dateivergleich", "", 0)
ReadFile(1,FileName1$)
While Eof(1)=0
Zeile.s=ReadString(1)
AddMapElement(Datei1(),Zeile.s,#PB_Map_ElementCheck)
AddElement(Liste1())
Liste1() = Zeile.s
Wend
CloseFile(1)
Anzahl_Datei1 = MapSize(Datei1())-1
TextGadget(5, 10, 10, 480, 30, "Datei_1: " + FileName1$ + Chr(10) + Chr(13) + "Anzahl: " + StrU(Anzahl_Datei1))
Case 6:
FileName2$ = OpenFileRequester("Wählen die zweite der zu vergleichenden Dateien aus", "F:\Dateivergleich", "", 0)
ReadFile(1,FileName2$)
While Eof(1)=0
Zeile.s=ReadString(1)
AddMapElement(Datei2(),Zeile.s,#PB_Map_ElementCheck)
AddElement(Liste2())
Liste2() = Zeile.s
Wend
CloseFile(1)
Anzahl_Datei2 = MapSize(Datei2()) - 1
TextGadget(6, 10, 40, 480, 30, "Datei_2: " + Filename2$ + Chr(10) + Chr(13) +"Anzahl: " + StrU(Anzahl_Datei2))
Case 7:
End
Case 8:
DeleteFile("Daten nur in Datei 2.txt")
DeleteFile("Doppelte Einträge.txt")
StartTime = ElapsedMilliseconds()
;-----------------------------------
ForEach Liste1()
Vergleich$ = Liste1()
If FindMapElement(Datei2(), Vergleich$)
;DeleteMapElement(Datei2(),Vergleich$)
Else
AddElement(Liste3())
Liste3() = Vergleich$
;DeleteMapElement(Datei2(),Vergleich$)
EndIf
Next
;--------------------------------
ForEach Liste2()
Vergleich$ = Liste2()
If FindMapElement(Datei1(), Vergleich$)
;DeleteMapElement(Datei1(),Vergleich$)
Else
AddElement(Liste4())
Liste4() = Vergleich$
;DeleteMapElement(Datei1(),Vergleich$)
EndIf
Next
;---------------------------------
Time =ElapsedMilliseconds() - StartTime
If CreateFile(0, "Daten nur in Datei 2.csv")
ForEach Liste3()
WriteStringN(0, Liste3())
Next
CloseFile(0)
Else
MessageRequester("Information","Konnte Datei nicht erstellen!")
EndIf
If CreateFile(0, "Daten nur in Datei 1.csv")
ForEach Liste4()
WriteStringN(0, Liste4())
Next
CloseFile(0)
Else
MessageRequester("Information","Konnte Datei nicht erstellen!")
EndIf
Anzahl_Datei3 = ListSize(Liste3())
Anzahl_Datei4 = ListSize(Liste4())
TextGadget(3, 10, 190, 250, 20, "Anzahl Datei2/Datei1: " + Str(Anzahl_Datei3))
TextGadget(4, 10, 220, 250, 20, "Anzahl Datei1/Datei2: " + Str(Anzahl_Datei4))
MessageRequester("Auswertezeit", Str(Time))
Case 11 ; About
MessageRequester("About", "Hilfsmittel zum Vergleich zweier Dateien", 0)
Default
MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Guten Abend,
nun habe ich noch ein wenig geändert. Das Umspeichern in die Hilfsvariable "Vergleich§" war natürlich nicht erforderlich. Nun hier der aktuelle Code.
Gibt es irgendeine Möglichkeit die Schleife noch etwas zu beschleunigen.
Schon einmal Danke für die Hilfe und auch nochmal Danke für die bisherige Hilfe.
nun habe ich noch ein wenig geändert. Das Umspeichern in die Hilfsvariable "Vergleich§" war natürlich nicht erforderlich. Nun hier der aktuelle Code.
Gibt es irgendeine Möglichkeit die Schleife noch etwas zu beschleunigen.
Schon einmal Danke für die Hilfe und auch nochmal Danke für die bisherige Hilfe.
Code: Alles auswählen
NewList Liste1.s()
NewList Liste2.s()
NewList Liste3.s()
NewList Liste4.s()
NewMap Datei1.s()
NewMap Datei2.s()
If OpenWindow(0, 100, 150, 500, 300, "Dateivergleich")
If CreateMenu(0, WindowID(0))
MenuTitle("Datei")
MenuItem( 5, "Datei_1")
MenuItem( 6, "Datei_2")
MenuBar()
MenuItem( 7, "&Quit")
MenuTitle("Vergleich")
MenuItem( 8, "Dateivergleich")
MenuTitle("?")
MenuItem(11, "About")
EndIf
; This is the 'event loop'. All the user actions are processed here.
; It's very easy to understand: when an action occurs, the Event
; isn't 0 and we just have to see what have happened...
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu
Select EventMenu()
Case 5:
FileName1$ = OpenFileRequester("Wählen die erste der beiden zu vergleichenden Dateien aus", "F:\Dateivergleich", "", 0)
ReadFile(1,FileName1$)
While Eof(1)=0
Zeile.s=ReadString(1)
AddMapElement(Datei1(), Zeile.s,#PB_Map_ElementCheck)
AddElement(Liste1())
Liste1() = Zeile.s
Wend
CloseFile(1)
Anzahl_Datei1 = MapSize(Datei1())-1
TextGadget(5, 10, 10, 480, 30, "Datei_1: " + FileName1$ + Chr(10) + Chr(13) + "Anzahl: " + StrU(Anzahl_Datei1))
Case 6:
FileName2$ = OpenFileRequester("Wählen die zweite der zu vergleichenden Dateien aus", "F:\Dateivergleich", "", 0)
ReadFile(1,FileName2$)
While Eof(1)=0
Zeile.s=ReadString(1)
AddMapElement(Datei2(),Zeile.s,#PB_Map_ElementCheck)
AddElement(Liste2())
Liste2() = Zeile.s
Wend
CloseFile(1)
Anzahl_Datei2 = MapSize(Datei2()) - 1
TextGadget(6, 10, 40, 480, 30, "Datei_2: " + Filename2$ + Chr(10) + Chr(13) +"Anzahl: " + StrU(Anzahl_Datei2))
Case 7:
End
Case 8:
DeleteFile("Daten nur in Datei 2.txt")
DeleteFile("Doppelte Einträge.txt")
StartTime = ElapsedMilliseconds()
;-----------------------------------
ForEach Liste1()
If FindMapElement(Datei2(), Liste1())
Else
AddElement(Liste3())
Liste3() = Liste1()
EndIf
Next
;--------------------------------
ForEach Liste2()
If FindMapElement(Datei1(), Liste2())
Else
AddElement(Liste4())
Liste4() = Liste2()
EndIf
Next
;---------------------------------
Time =ElapsedMilliseconds() - StartTime
If CreateFile(0, "Daten nur in Datei 2.csv")
ForEach Liste3()
WriteStringN(0, Liste3())
Next
CloseFile(0)
Else
MessageRequester("Information","Konnte Datei nicht erstellen!")
EndIf
If CreateFile(0, "Daten nur in Datei 1.csv")
ForEach Liste4()
WriteStringN(0, Liste4())
Next
CloseFile(0)
Else
MessageRequester("Information","Konnte Datei nicht erstellen!")
EndIf
Anzahl_Datei3 = ListSize(Liste3())
Anzahl_Datei4 = ListSize(Liste4())
TextGadget(3, 10, 190, 250, 20, "Anzahl Datei2/Datei1: " + Str(Anzahl_Datei3))
TextGadget(4, 10, 220, 250, 20, "Anzahl Datei1/Datei2: " + Str(Anzahl_Datei4))
MessageRequester("Auswertezeit", Str(Time))
Case 11 ; About
MessageRequester("About", "Hilfsmittel zum Vergleich zweier Dateien", 0)
Default
MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Hatte vergessen was zur Geschwindigkeit zu sagen:
Rechner: Netbool 1,7 GHz (MonoCore); Win7
Datei 1 ca. 11000 Zeilen mit jeweils ca. 120 Zeichen pro Zeile
Darei 2 ca. 10000 Zeilen mit jeweils ca. 120 Zeichen pro Zeile
Zeit: 110ms
Rechner: Netbool 1,7 GHz (MonoCore); Win7
Datei 1 ca. 11000 Zeilen mit jeweils ca. 120 Zeichen pro Zeile
Darei 2 ca. 10000 Zeilen mit jeweils ca. 120 Zeichen pro Zeile
Zeit: 110ms
Re: Stringvergleich
Eine Map ist am schnellsten, wenn sie genügend Slots für die Elemente hat. Es wäre daher sinnvoll, die Map mit mehr Slots zu erstellen. Zum Testen kannst du beim Erstellen der Map in die Klammer einfach mal 10000 Eintragen. Das sollte noch etwas bringen.
Das Problem ist, daß man vor dem Laden der Datei die Anzahl der Elemente noch nicht kennt. Ich denke daher, daß es besser wäre, erst nur die LinkedList zu füllen. Danach kennst du die Anzahl der Elemente und kannst die Map auch mit der optimalen Anzahl von Slots anlegen.
Mir ist aufgefallen, daß du vor dem Laden einer Datei die LinkedList nicht leerst. Das gibt falsche Ergebnisse, wenn sie von einem vorherigen Programmlauf schon Daten enthält.
Das Problem ist, daß man vor dem Laden der Datei die Anzahl der Elemente noch nicht kennt. Ich denke daher, daß es besser wäre, erst nur die LinkedList zu füllen. Danach kennst du die Anzahl der Elemente und kannst die Map auch mit der optimalen Anzahl von Slots anlegen.
Mir ist aufgefallen, daß du vor dem Laden einer Datei die LinkedList nicht leerst. Das gibt falsche Ergebnisse, wenn sie von einem vorherigen Programmlauf schon Daten enthält.
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Vielen Dank matbal,
ich habe deine Vorschläge umgesetzt. Die Bearbeitungszeit hat sich nun von 110ms auf 62ms reduzuiert, Nicht schlecht die kleine Änderung.
Gibt es nicht noch eine Möglichkeit in der Schleife was zu optimieren?
Z.B. Delete ...; Doch wenn ich das mache, verlängert sich die Ausführung. Eigentlich müsste es doch schneller gehen, da die Datei immer kleiner wird. Aber das ist nich so!
Nun habe ich die Liste noch durch eine Map ersetzt: Ergebnis: 47ms
Vielen Vielen Dank für die Hilfe
__________________________________________________
Code-Tags hinzugefügt
28.04.2013
RSBasic
ich habe deine Vorschläge umgesetzt. Die Bearbeitungszeit hat sich nun von 110ms auf 62ms reduzuiert, Nicht schlecht die kleine Änderung.
Gibt es nicht noch eine Möglichkeit in der Schleife was zu optimieren?
Z.B. Delete ...; Doch wenn ich das mache, verlängert sich die Ausführung. Eigentlich müsste es doch schneller gehen, da die Datei immer kleiner wird. Aber das ist nich so!
Code: Alles auswählen
ForEach Liste1()
If FindMapElement(Datei2(), Liste1())
;DeleteMapElement(Datei2())
Else
AddElement(Liste3())
Liste3() = Liste1()
EndIf
Next
Code: Alles auswählen
ForEach Liste1()
If FindMapElement(Datei2(), Liste1())
;DeleteMapElement(Datei2())
Else
AddMapElement(Datei3(), Liste1(),#PB_Map_ElementCheck)
; AddElement(Liste3())
; Liste3() = Liste1()
EndIf
Next
__________________________________________________
Code-Tags hinzugefügt
28.04.2013
RSBasic
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Gutnen Abend!
Kann man mit PureBasic voneinander unabhängige Programmteile zwei verschiedenen Prozessorkernen zuweisen?
z.B eine Berechnung in einer Schleife 1 der Kern 1
und eine andere Berechnung in einer Schleife 2 dem Kern 2
Kann man mit PureBasic voneinander unabhängige Programmteile zwei verschiedenen Prozessorkernen zuweisen?
z.B eine Berechnung in einer Schleife 1 der Kern 1
und eine andere Berechnung in einer Schleife 2 dem Kern 2
Re: Stringvergleich
Du kannst mehrere Sachen aufteilen: http://www.rsbasic.de/aktualisierung/wi ... rteilen.pb
-
- Beiträge: 282
- Registriert: 03.01.2005 11:36
Re: Stringvergleich
Vielen Dank RSBasic,
bevor ich mit mehreren Kernen arbeiten kann, muss ich wohl zuerst noch einiges lernen.
Wie mache ich folgendes am besten?
Nun habe ich es hinbekommen die beiden zu vergleichenden Strings in den Speicher zu schreiben. Das „Null-Zeichen“ am Ende des jeweilig kopierten Strings wird aber mit dem Code (siehe unten) nicht eingefügt bzw. überschrieben. Wenn ich nach jedem Schreibvorgang die Adresse um eins erhöhe klappt es. Ob das so aber korrekt und auch sinnvoll ist, weiß ich nicht.
Wenn man das so macht, dann müsste es auch mit dem „CompareMemoryString“ klappen, ohne dass ich eine Längenangabe mache. Wenn ich CompareMemory nehme brauche ich immer eine Längenangabe. deshalb habe ich zwei Hilfsfelder angelegt, in die ich die Länge jedes Strings eintrage.
Kann mir bitte jemand weiterhelfen, wie ich es am besten hinbekomme, mit CompareMemoryString oder comparememory in einer Schleife die Strings vergleichen kann.
Schon einmal vielen Dank für die Hilfe.
Hier der Code:
bevor ich mit mehreren Kernen arbeiten kann, muss ich wohl zuerst noch einiges lernen.
Wie mache ich folgendes am besten?
Nun habe ich es hinbekommen die beiden zu vergleichenden Strings in den Speicher zu schreiben. Das „Null-Zeichen“ am Ende des jeweilig kopierten Strings wird aber mit dem Code (siehe unten) nicht eingefügt bzw. überschrieben. Wenn ich nach jedem Schreibvorgang die Adresse um eins erhöhe klappt es. Ob das so aber korrekt und auch sinnvoll ist, weiß ich nicht.
Wenn man das so macht, dann müsste es auch mit dem „CompareMemoryString“ klappen, ohne dass ich eine Längenangabe mache. Wenn ich CompareMemory nehme brauche ich immer eine Längenangabe. deshalb habe ich zwei Hilfsfelder angelegt, in die ich die Länge jedes Strings eintrage.
Kann mir bitte jemand weiterhelfen, wie ich es am besten hinbekomme, mit CompareMemoryString oder comparememory in einer Schleife die Strings vergleichen kann.
Schon einmal vielen Dank für die Hilfe.
Hier der Code:
Code: Alles auswählen
Dim a.s(20000)
Dim b.s(20000)
Dim c.s(20000)
Dim a_laenge(20000)
Dim b_laenge(20000)
a(1) = "Wald"
a(2) = "Baum"
a(3) = "Ast"
a(4) = "Blatt"
b(1) = "Hund"
b(2) = "Maus"
b(3) = "Katze"
b(4) = "Ast"
b(5) = "Vogel"
b(6) = "Wald"
Anzahl_a = 4
Anzahl_b = 6
String1$ = a(1)
*String1 = @String1$
String2$ = b(1)
*String2 =@String2$
*BufferString1 = AllocateMemory(10000000)
*PointerString1 = *BufferString1
*BufferString2 = AllocateMemory(10000000)
*PointerString2 = *BufferString2
;-----------------------------------------------------------
Ergebnis = CopyMemoryString(a(1), @*PointerString1)
a_laenge(1) = Len(a(1))
For i= 2 To Anzahl_a
CopyMemoryString(a(i))
a_laenge(i) = Len(a(i))
;Debug PeekS(*BufferString1)
Next
;-----------------------------------------------------------
CopyMemoryString(b(1), @*PointerString2)
b_laenge(1) = Len(b(1))
For i = 2 To Anzahl_b
CopyMemoryString(b(i))
b_laenge(i) = Len(b(i))
Next
;----------------------------------------------------------
;Debug PeekS(*BufferString1)
;Debug PeekS(*BufferString2)
;StringBuffer1$ = PeekS(*BufferString1)
;Debug StringBuffer1$
*AdresseString2 = *BufferString2
StartTime = ElapsedMilliseconds()
For i = 1 To Anzahl_b
;Debug b(i)
; How do I have to set and calculate *BufferString2 in order to use the function CompareMemory ()????????
MessageRequester("",PeekS(*BufferString1, a_laenge(1)) + " " + PeekS(*AdresseString2, b_laenge(i)))
If CompareMemory(*BufferString1, *AdresseString2, b_laenge(i)) = 0 ;???????????????????
NichtGefunden = NichtGefunden + 1
c(NichtGefunden) = PeekS(*BufferString2)
Else
EndIf
*AdresseString2 = *AdresseString2 + b_laenge(i)
Next
Time =ElapsedMilliseconds() - StartTime
MessageRequester("Auswertezeit", Str(Time))
MessageRequester("","Nicht gefunden" + Str(NichtGefunden))