Seite 1 von 2

Wichtig: Offizielle dauerhaftes verhalten!?

Verfasst: 03.01.2007 02:08
von Toshy
Hallo.

Ich hatte schon öfter mit den Vor- und Nachteilen der Strukturen zu kämpfen. Falls man größere Werte / Daten als ein Quad (intern wohl zwei Longs oder ähnlich) verwenden möchte, so hat man ein Problem wenn es auf Geschwindigkeit ankommt. Man hat dann nur die Möglichkeit Strings in Strukturen zu verwenden, z.B. wenn man IPs der Protokollversion 6 nutzen will (128bit). Da in Strukturen immer nur die Pointer verwendet werden, wird also beim auslesen bzw. Schreiben (bzw. vergleichen) im Speicher auf einen "eigendlich vom Strukturspeicher unabhängigen" Speicher zugegriffen, also recht weit gesprungen. Ich hatte das schon öfter getestet und ist langsamer als im zusammenhängen Bereich. Also habe ich das damals erstmal gelassen und nicht mit "Strings" gearbeitet, sondern gleich mit eigenen "Memoryspeichern" deren Pointer in die Struktur geschrieben. Nun habe ich einfach mal aus neugier einen "längenbegrenzten String" in die Struktur aufgenommen und siehe da, dieser String wird DIREKT in die Struktur geschrieben (nur mit SizeOff überprüft). Ist das wirklich so? Wäre an sich ja recht toll, aber warum bitte steht das nirgens mal angemerkt oder habe ich das überlesen?

Also es wäre nett, wenn hier vielleicht Andre das offiziell bestätigt oder widerlegt.

Welche Möglichkeit gibt es die Speicherstelle / Zeiger zu erfahren, wo genau dieser String in der Struktur steht? Geht das mit Offset und was gibt dies genau zurück, die Indexnummer an welcher Stelle in der Struktur dieser EIntrag steht oder das Byte an deren Stelle in der STruktur er beginn? nur wenn man schnell und direkt an die Stelle kommt, mann man dann den String direkt verarbeiten, denn ansonsten kann man ja kein eNULL-Bytes nutzen.

Gruß
Toshy

Verfasst: 03.01.2007 03:22
von ts-soft

Code: Alles auswählen

Structure Person
  Name.s{40}
  ForName.s{40}
  Age.w 
EndStructure
  
Debug OffsetOf(Person\Age)
 
Structure Speicher
  Buffer1.b[40]
  IP6.b[16] ; 128bit
EndStructure

Debug OffsetOf(Speicher\IP6)
Debug SizeOf(Speicher\IP6)
Geht doch alle. In PB 3.94 konnte man auch Bytes für Strings nehmen,
mußte diese aber hineinpoken. Ansonsten geht doch alles, seit ewig :mrgreen:

Re: Wichtig: Offizielle dauerhaftes verhalten!?

Verfasst: 03.01.2007 23:28
von Andre
Toshy hat geschrieben: Also es wäre nett, wenn hier vielleicht Andre das offiziell bestätigt oder widerlegt.
Da ts-soft ja schon eine Antwort gegeben hat, weiß ich jetzt nicht, ob diese für Dich ausreichend ist.

Ansonsten müsste ich freak um eine Stellungnahme bitten, da ich mangels Einblick selbst keine "offiziellen" Stellungnahmen zu technischen Fragen abgeben kann.
(Jedenfalls nicht ohne umständliches Nachfragen....)

Verfasst: 03.01.2007 23:38
von Toshy
Hallo.
Ich wußte nicht,das dies schon lange und auch mit anderen Typen geht. In der Hilfe stand unter Strukturen davon nichts. Aber was trotzdem interessant zu wissen wäre ist die schon gestellte Frage, ob das (bezogen auf String) absichtlich so ist.

Structure Person1
Name.s
EndStructure
string.person1 = Space(40)

die struktur ist hier 4 byte lange (Datenteil), halt ein Pointer

Structure Person2
Name.s{40}
EndStructure

und hier 40 byte lange.
In Strunkturen nutze ich das bisher nicht, da mir das nicht bekannt war und in der Beschreibung der Variablen und Operatoren stand bei var.s[laenge] nur, das hier eine feste länge vorgegeben ist. ich aber davon ausgegangen bin, das hier auch in der struktur nur der Pointer zu dem "längenfesten String" steht.

Wenn das aber offiziell ist wie ich es bemerkt habe, dann ist ja gut. Sollte aber dann mal deutlich in der Hilfe stehen. :-)

Gruß und Danke
Toshy

Verfasst: 03.01.2007 23:42
von Toshy
Hallo Andre,
da hat sich deine Antwort mit meiner zeitlich überschnitten. Tja, offiziel was zu wissen ist immer gut, aber wenn dieses verhalten schon langen vielen Bekannt ist, dann denke ich ist das in diesem Falle ausreichend. War wir halt nur zufällig aufgefallen. Ich denke das reicht mir.

Ich habe jetzt erstmal mit einem wie ich vermute Bug im NetworkServer von PB zu kämpfen bzw. wie ich vermute einen strukturellen Denkfehler. Wer dazu in Kürze, bin da noch am testen.

Gruß und Danke
Toshy

Verfasst: 04.01.2007 01:36
von ts-soft
Toshy hat geschrieben: Structure Person2
Name.s{40}
EndStructure

und hier 40 byte lange.
Sie ist 40 char lang!!!
In Unicode also 80 Byte

Gruß
Thomas

Verfasst: 04.01.2007 13:12
von ShadowTurtle
Ich denke das dieses Feature selbst noch Beta ist und deswegen auch nichts in der Doku steht. Warum kompliziert denken, wenns auch einfacher zu begreifen ist?

Verfasst: 04.01.2007 13:55
von Toshy
Das hat nichts mit einfacher zu begreifen zu verstehen. Das es überhaupt geht findet man nicht in der Hilfe, auf jedenfall nicht dort wo man es erwartet und was wichtiger ist, es ist ein gaaanz großer Unterschied ob die Daten direkt in der Struktur stehen oder nur der Pointer. Sobald man direkt auf die Daten zugreift ist das mit dem Pointer der Strings viel langsamer bei vielen Dingen. Das merkt man natürlich erst, wenn das Programm an die Grenzen der Prozessorlast geht bzw. der Rechner, aber genau darum geht es mir ja. hehe.

Verfasst: 04.01.2007 19:36
von ShadowTurtle
Hm... na dann...

its not a feature, its a bug

Verfasst: 04.01.2007 22:14
von jear
Als ich damals an der Stelle angekommen war, habe ich mir diese beiden Snippets (aktuell an PB 4 angepasst) geschrieben. Damit kann man sehen, wie es geht und wie es nicht geht.

Der nicht so tief einblickende Nutzer sollte entweder durch entsprechend deutliche Hinweise in den Hilfen, besser noch durch einen Compilerwarnung darauf aufmerksam gemacht werden, dass er beim Speichern von Strukturen, die normale Strings enthalten, nur die Pointer und nicht die Strings speichert.

Noch besser wäre es natürlich, wenn PB in einem solchen Falle die Stringsektion mit in die Datei schreibt, beim Einlesen in den Stringspeicher der aktuellen Anwendung aufnimmt und die Pointer in den Arrays automatisch aktualisiert.

Code: Alles auswählen

; Stringstruktur schreiben
Structure Adresse
  Satz.l : 
  ;Name.s : Vorname.s         ; Strings variabler Länge
  Name.s{10} : Vorname.s{10} ; Strings fester Länge
EndStructure

; Array anlegen und füllen
Dim Adresse.Adresse(3)
Adresse(0)\Satz = 10 : Adresse(0)\Name = "Müller"   : Adresse(0)\Vorname = "Gerd"
Adresse(1)\Satz = 11 : Adresse(1)\Name = "Liebrich" : Adresse(1)\Vorname = "Karl"
Adresse(2)\Satz = 12 : Adresse(2)\Name = "Walter"   : Adresse(2)\Vorname = "Fritz"
Adresse(3)\Satz = 13 : Adresse(3)\Name = "Schäfer"  : Adresse(3)\Vorname = "Hans"

; Array speichern
If CreateFile(1, "Test.dat")
  WriteData(1, @Adresse(idx), 4 * SizeOf(Adresse)) : CloseFile(1)
EndIf

End

Code: Alles auswählen

; Stringstruktur lesen
Structure Adresse
  Satz.l : 
  ;Name.s : Vorname.s         ; Strings variabler Länge
  Name.s{10} : Vorname.s{10} ; Strings fester Länge
EndStructure

Define.s out
Define.l idx, idx1

; Array zum Einlesen anlegen und füllen
Dim Adresse1.Adresse(100)

; Array einlesen
If ReadFile(1, "Test.dat")
  Laenge = Lof(1)
  ReadData(1, @Adresse1(), Lof(1)) : CloseFile(1)
EndIf

; Was steht in der Datei
While idx < Laenge 
  For idx1 = 0 To SizeOf(Adresse)
    out + RSet(Str(255 & PeekB(@Adresse1() + idx + idx1)), 3, "0") + " | "
  Next
  Debug out
  out = "" : idx + SizeOf(Adresse)
Wend

; Welche Strings stehen drin?
For idx = 0 To 3
  Debug Str(Adresse1(idx)\Satz) + " | " + Adresse1(idx)\Name + " | " + Adresse1(idx)\Vorname
Next

End