| |
Fortgeschrittene ProgrammierungString auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 08.04.19 12:19 |
| Hallo,
ich habe ein kleines Performanceproblem mit Strings:
Ich habe eine Collection mit vielen Items, die jeweils einen kurzen String behinhalten.
Nun muss ich diese Items aneinanderhängen, damit daraus ein einzelner String wird, den ich in die Datenbank schieben kann. (Für einen Volltextindex)
Bei wenigen Teilen ist das keine Problem:
strText = strText & " " & strSchnipsel(n) Wenn die Zahl n dann aber sehr groß wird, dann wird das heftig langsam.
Welche anderen Möglichkeiten habe ich denn noch für diese Aktion?
Mir fällt nichts mehr ein.
Gruß
Bernd | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 08.04.19 16:05 |
| Hallo Zardoz,
das wäre eine Möglichkeit, an die habe ich noch nicht gedacht.
Dann muss ich zuerst die Collection in ein Array wandeln und dann mit Join zusammenfügen.
Das teste ich gleich aus.
Ich habe deshalb die Collection genommen, weil ich auf schnelle und einfache Weise Duplikate verhindern wollte.
Ich lese den Plaintext von PDF-Dokumenten aus und überführe den Inhalt in eine Volltextsuche.
Da kommen viele Wörter doppelt vor.
Nach dem Test gebe ich Bescheid.
Gruß
Bernd | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 08.04.19 16:46 |
| Hi Zardoz,
mit Join geht es wesentlich schneller.
Die Übergabe von der Collection in das Array dauert zwar ein wenig, aber join ist dann blitzschnell.
Vielen Dank für den Tip. | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Manfred X | Datum: 08.04.19 18:09 |
| Hallo!
Wenn ich recht erinnere, kannst Du einen WhiteChar-String in Gesamtlänge Deiner
Einträge erstellen und per MID$-Funktion die Collection-Items direkt an die
entsprechenden Positionen in diesem String eintragen. | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 25.04.19 16:22 |
| Sorry Manfred,
der Eintrag ging an mir vorbei. Irgendwie waren die letzten Tage etwas hektisch.
Das probiere ich auch mal aus.
Ich gebe dann wieder Bescheid. | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 25.04.19 16:42 |
| Hi,
gerade mal probiert.
Leider gibt mid$ nur einen Wert zurück.
Direkt schreiben kann man (in VBA) damit nicht.
strInput = Space$(lngLength) ' Gesamtstring mit Leerzeichen erstellen
For n = 1 To colText.Count ' Stückweise übergeben
Mid$(strInput, lngPos, Len(colText.Item(n))) = colText.Item(n)
lngPos = lngPos + Len(colText.Item(n)) + 1
Next Wäre aber "toll" gewesen, wenn man so direkt schreiben könnte.
Gruß
Bernd | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Zardoz | Datum: 25.04.19 17:00 |
| Hallo Bernd,
Mid$ gibt es als Funktion und als Anweisung. Das
sollte funktionieren. Ich vermute nur, dass es
nicht sehr schnell ist. Du greifst in deinem
Beispiel bei einem Schleifendurchlauf dreimal
auf die selbe Collection zu. Es ist wahrscheinlich
schneller den Collection-Wert in einer Variablen
zu speichern.
Zu Mid$ siehe hier unter "Wichtiger Hinweis":
https://www.vbarchiv.net/commands/cmd_mid.html
Gruss,
Zardoz | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 25.04.19 17:28 |
| Hi Zardoz,
wieder was gelernt. Bei den "Basics" lernt man nie aus ...
Klar, mit mid funktioniert es richtig.
Ich habe mal geprüft, wie lange es dauert
dblTimer = Timer
Debug.Print "Start Anzahl Items = " & colText.Count
lngLength = 0 ' Gesamtlänge ermitteln
For n = 1 To colText.Count
lngLength = lngLength + Len(colText.Item(n)) + 1
Next
Debug.Print "Step1: " & Format$(Timer - dblTimer, "0.00"), "Länge = " & _
lngLength
dblTimer = Timer
lngPos = 1
strInput = Space$(lngLength) ' Gesamtstring mit Leerzeichen erstellen
For n = 1 To colText.Count ' Stückweise übergeben
Mid(strInput, lngPos, Len(colText.Item(n))) = colText.Item(n)
lngPos = lngPos + Len(colText.Item(n)) + 1
Next
Debug.Print "Step2: " & Format$(Timer - dblTimer, "0.00") Ergebnis:
Start Anzahl Items = 9066
Step1: 0,19 Länge=86172
Step2: 0,63 Das war eine PDF-Datei mit 7 MB. Die musste ich aus der Datenbank holen, auf die Platte schieben, dann mit PdfToText auslesen und dann die Textdatei verarbeiten.
Diese knappe Sekunde ist dann "verschmerzbar"
Aber:
Die bisherige Methode habe ich auch mal über Debug-Timer geprüft:
ReDim strWords(colText.Count)
For n = 1 To colText.Count
strWords(n - 1) = colText.Item(n)
Next
strInput = Join(strWords) Da waren es nur 0,25 Sekunden
Also war die Aussage richtig, dass es nicht besonders schnell sein wird.
Euch allen vielen Dank für die Hilfe. | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Zardoz | Datum: 25.04.19 17:48 |
| Hallo Bernd,
ich habe noch eine Möglichkeit ohne Collection.
Trage alle Texte (auch die Doppelten) in ein
Array ein und rufe die Funktion Array_to_Str auf.
Private Function Array_to_Str(TxtLst() As String) As String
Dim i&, Txt$, C$
Call QuickSort(TxtLst, LBound(TxtLst), UBound(TxtLst))
C = Chr$(1)
Txt = C
For i = LBound(TxtLst) To UBound(TxtLst)
If Txt = TxtLst(i) Then
TxtLst(i) = C
Else
Txt = TxtLst(i)
End If
Next i
Array_to_Str = Join(Filter(TxtLst, C, False))
End Function
Private Sub QuickSort(SortArr() As String, ByVal LB As Long, ByVal UB As Long)
Dim P1&, P2&, Pivot$, Tmp$
P1 = LB
P2 = UB
Pivot = SortArr((P1 + P2) / 2)
Do
Do While SortArr(P1) < Pivot: P1 = P1 + 1: Loop
Do While SortArr(P2) > Pivot: P2 = P2 - 1: Loop
If P1 <= P2 Then
Tmp = SortArr(P1): SortArr(P1) = SortArr(P2): SortArr(P2) = Tmp
P1 = P1 + 1
P2 = P2 - 1
End If
Loop Until P1 > P2
If LB < P2 Then Call QuickSort(SortArr, LB, P2)
If P1 < UB Then Call QuickSort(SortArr, P1, UB)
End Sub Gruss,
Zardoz | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Manfred X | Datum: 25.04.19 20:11 |
| Hallo!
Du fragst mehrfach die Länge der Items ab (Len).
Erledige das einmal in der ersten Schleife und speichere
die Längen in einem Integer-Array. | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 26.04.19 09:01 |
| Hallo Zardoz,
vielen Dank für den Code und die Zeit, die du dir dafür genommen hast.
Erstmal: Er funktioniert prächtig!
Ich gebe zu, dass mich der Ablauf mental etwas überfordert.
Vom Prinzip her ist es klar - die einzelnen Einträge werden einsortiert und dabei werden die Duplikate übergangen.
Bei Arrays bis 10000 ist das Ding blitzschnell!
Bei größeren Arrays scheint es dann zu kippen. Dann wird die "alte" Methode wieder schneller.
Ich habe jetzt noch nicht genau herausgefunden, an welcher Stelle ich eine Abfrage für den einzelnen Teilstring einfügen könnte, in der ich bestimmte Konstellation filtern kann. Bei meiner Methode war das die Übergabe in die Collection.
Aktuell habe ich z.B. diese Einträge:
deaktivieren deaktivieren: deaktiviert deaktiviert! deaktivierter Deaktivierung defekt defekt! defekt" defekt) defekt)" defekt, defekt: defekte Defekten Defektes definieren definiert definiert? Definierte Definition Definitionsparameter deklariert dem den denen der deren des deshalb desto deswegen detaillierte detailliertere Details detektiert Deublin) DEV.] Dezimalcode Dezimalzahl.) diag Diag- Diagn Diagnose Diagnose" Diagnose) Diagnosebild Diagnoseelektronik Diagnosemenü Diagnosemenüs Diagnoseübersicht Dichtungen die die, dient Dies Diese diesem diesen Dieser dieses Differenz Differenzdruckmessgerät Differenzdruckschalter Digital direkt direkte direktem direkten direkter
Gruß
Bernd | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Benne | Datum: 26.04.19 09:04 |
| Hallo Manfred,
stimmt!
Das habe ich nicht gesehen. Damit kann ich Zeit sparen.
Ich werde das so einbauen.
Gruß
Bernd | |
Re: String auf vielen Einzelteilen zusammensetzen | | | Autor: Manfred X | Datum: 26.04.19 09:54 |
| Hallo!
Der von Zardoz verwendete Quicksort-Algorithmus funktioniert blitzschnell bei
unsortierten Eingangsdaten. Je stärker die Eingangsliste bereits vorsortiert ist,
mit desto stärkeren Leistungseinbußen ist zu rechnen. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|