Pointer Problem

Anfängerfragen zum Programmieren mit PureBasic.
nexus72
Beiträge: 25
Registriert: 17.11.2007 14:18

Pointer Problem

Beitrag von nexus72 »

Hallo Zusammen,

ich hätte da mal eine Frage zu den Pointern. Ich habe mir jetzt alle
Informationen zu Pointern durchgelesen, jedoch, wenn ich das
in ein Beispiel umsetzten will, krieg ich es nicht hin.

Also folgenden Code habe:

Code: Alles auswählen

;***** Structuren definieren
Structure structTab
  lId.l
  sName.s
EndStructure

Structure structZellinh
  lId.l
  lZeile.l
  lSpalte.l
  sZelleninh.s
EndStructure

Structure structZeile
  lId.l
  lZeile.l
  qStringHash.q
EndStructure
;***** Structuren definieren Ende

;***** LinkedList
Global NewList DB1Tab.structTab()
Global NewList DB1Zellinh.structZellinh()
Global NewList DB1Zeile.structZeile()

Global NewList DB2Tab.structTab()
Global NewList DB2Zellinh.structZellinh()
Global NewList DB2Zeile.structZeile()
;***** LinkedList Ende

;... Hier folgt der Code zum füllen der LinkedListen

; Anschließend vergleiche ich diese beiden Linkedlisten DB1 mit DB2

ForEach DB2Zeile()
  ForEach DB1Zeile()
    If DB2Zeile()\qStringHash=DB1Zeile()\qStringHash
      lx.l = 1
    EndIf
  Next
  ; CallDebugger
  If lx = 1
    ; Debug "Datensatz vorhanden" + Str(DB2Zeile()\qStringHash)
  Else
    Debug "Datensatz nicht vorhanden"
  EndIf
  lx = 0
Next
Nun bin ich mir nicht ganz sicher, ob ich hier Pointer einsetzen kann.
Ich denke ja, nur ich weis noch nicht genau wie.
Besonders weis ich nicht ob der Vergleich der beiden Linkedlisten
durch Pointer beschleunigt wird, da ich ja hier nur StringHash (longs)
vergleiche.
Nur als Hinweis: DB1 und DB2 beinhalten je 180.000 Datensätze.
Dadurch wird ja der Vergleich erheblich Zeit verbrauchen. Geht
es mit Pointern schneller????
Ich hoffe es könnte mir hier jemand Hilfestellung geben, damit ich
anhand des o. g. Code das mit den Pointern verstehen lerne.

Schon mal vielen Dank für Eure Mühe.

Viele Grüße
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Hi,

also mit Pointern müsstest du das ungefähr so machen:
Du musst:
If DB2Zeile()\qStringHash=DB1Zeile()\qStringHash
durch das:
If CompareMemory(*DB2Zeile()\qStringHash,*DB1Zeile()\qStringHash,4)
4, weil eine Long Variable 4 Byte "lang" ist.
ersetzen.

und dann noch die Geschwindigkeit !ohne Debugger! vergleichen.

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Scarabol hat geschrieben: If CompareMemory(*DB2Zeile()\qStringHash,*DB1Zeile()\qStringHash,4)
Das geht so nicht.

Was helfen würde, wäre ein Array anstatt einer LL zu nehmen.
Wenn die Grösse Anfangs unbekannt ist, kannst du ja per ReDim beim Einlesen das Array jeweils vergrössern ohne die bis dahin enthaltenen Elemente zu verlieren.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Why?

Mit @ vielleicht?

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

@nexus72
das einzige was du an operationen zeigst ist

Code: Alles auswählen

    If DB2Zeile()\qStringHash=DB1Zeile()\qStringHash
ob du da was mit pointern bastelst ist der geschwindigkeit ziemlich egal.
wenn du den grundzugriff über pointer realisieren willst geht das mit LLs nicht, sondern nur über arrays. die wären dann in manchen sachen auch schneller, aber eine (geschachtelte) foreach-schleife mit einem einfachen quadvergleich macht auf arrays umgestellt keinen wirklichen unterschied in geschw. (hab ich aber nicht getestet 8) ).
das iterieren durch eine liste ist nicht langsam, sondern eher sachen wie AddElement().
my pb stuff..
Bild..jedenfalls war das mal so.
nexus72
Beiträge: 25
Registriert: 17.11.2007 14:18

Beitrag von nexus72 »

Hallo Zusammen,
hallo #Null, Scarabol, HeXOR

vielen Dank für Eure Hilfe.

Also, wenn ich das richtig verstehe, dann wäre selbst, wenn ich den
Grundzugriff über ein Array incl. Pointer realisiere, kein großer Geschwindigkeits-
unterschied zu dem derzeitigen Programmcode zu erreichen?

Könntest Du mir mal ein Beispiel für den Grundzugriff über Pointer und Array
in Abänderung des o. g. Code geben. Das wäre super.

Schon mal vielen Dank für Eure Mühe.

Viele Grüße
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

was dagegen wenn wir aus den 3 structures und den 6 listen erstmal 1 Structure und 2 listen machen?
..oder einfacher 3 Strc. und 2 LLs/arrays

<edit>
ne, is wurst.

also so ein dynamisches pointer array kannst du in etwa so benutzen:
(das array wird in groesseren schritten, und damit seltener neu dimensioniert)

Code: Alles auswählen

Structure struct
  a.l
  b.l
  c.l
EndStructure

max = 0
max_arr = 0

Dim *arr.struct(max)


Procedure add(*p.struct, _a, _b)
  max +1
  If max > max_arr
    max_arr + 1 + max_arr/4
    ReDim *arr.struct(max)
  EndIf
  *arr(max) = AllocateMemory(SizeOf(struct)
  If *arr(max)
    *arr(max)\a = _a
    *arr(max)\b = _b
    *arr(max)\c = 12345
  EndIf
  ProcedureReturn *arr(max)
EndProcedure


;...

For i=0 To max
  For k=0 To max
    If *arr_one(i)\a = *arr_two(i)\a
      ;...
    EndIf
  Next
Next
my pb stuff..
Bild..jedenfalls war das mal so.
nexus72
Beiträge: 25
Registriert: 17.11.2007 14:18

Beitrag von nexus72 »

Hallo #Null,

super, vielen Dank für Dein Beispiel.

Ich habe gerade den Code ausgeführt und erhalte folgende Fehlermeldung
in folgender Code-Zeile:

Code: Alles auswählen

    ReDim *arr.struct(max)
und zwar: ReDim can't be used on a non-declared array: arr()

Könntest Du hier noch mal draufschauen?

Vielen Dank und viele Grüße
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Es gibt ein sehr gutes Tutorial von Freak. Sollte man auf jeden fall lesen
http://freak.purearea.net/ -> Help -> Pointer Tutorial

Hier ein kleine beispiel nur mit Pointer auf Strukturen und AllocateMemory

Code: Alles auswählen

;-TOP

; Struktur Datenanlegen
Structure udtDaten
  RecID.l
  Date.l
  Val.l
  Text.s{32} ; Mit festen String. kann man besser den Datensatz kopieren
EndStructure

; Struktur Array anlegen
Structure udtArray_of_Daten
  size.l
  id.udtdaten[0] ; <- Eigendlich nur ein Datensatz. PB macht aber keine Überwachung bei Bereichsverletzung ;)
EndStructure

; Ein Zeiger (Pointer) auf die Daten anlegen - Noch gibt es keine Speicher dafür
Global *daten.udtArray_Of_daten

; Kleine Hilfsfunktion um Speicher anzufordern
Procedure InitDaten(size)
  Protected *result.udtArray_of_daten
  *result = AllocateMemory(size * SizeOf(udtdaten) + 4) ; 4 Byte for Size
  If *result
    *result\size = size
  EndIf
  ProcedureReturn *result
EndProcedure

; Speicher anfordern
*daten = InitDaten(1000)
If *daten = 0
  Debug "Kein Speicher mehr"
  End
EndIf
; Mit Daten Arbeiten
For i = 0 To *daten\size -1
  With *daten\id[i]
    \RecID = i + 100
    \Text = "RecID: " + Str(\RecID)
  EndWith
Next
; Daten ausgeben
For i = 0 To *daten\size -1 Step 10
  With *daten\id[i]
    Debug "ID " + Str(i) + ":" + \Text
  EndWith
Next
FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
nexus72
Beiträge: 25
Registriert: 17.11.2007 14:18

Beitrag von nexus72 »

Hallo Zusammen,
hallo mk-soft,

vielen Dank für das Beispiel und für den Tip mit dem Tutorial.

Hatte einfach nur irgendwie das Problem mit dem Umsetzen
in den Code aus meinem Posting.

Nochmals vielen Dank für Deine / Eure Mühe.

Viele Grüße
Antworten