Results 1 to 6 of 6

Thread: typed records; gebruik van string vs shortstring

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,531

    typed records; gebruik van string vs shortstring

    voorbeeld 1:
    Delphi Code:
    1. Tfoo = record
    2.   regel1 : string[10];
    voorbeeld 2:
    Delphi Code:
    1. Tfoo = record
    2.   regel1 : string;
    Welk voorbeeld is het meest logisch om te gebruiken?

    Voorbeeld 1 resulteert tot een vaste lengte van een variable. Als er drie karakters worden gebruikt in variabele, wordt er toch 255 karakters gereserveerd in het geheugen (wat eigenlijk zinloos is, omdat er maar maximaal tien worden gebruikt).
    Voorbeeld 2 geeft een pointer terug naar de variabele. Tijdens het vullen van deze variabele wordt er geheugen @runtime gereserveerd naar mate het aantal tekens. Dit kan een vertraging oplopen.

    In Delphi wordt string[10] gezien als een shortstring (zelfs in D10 rio). Dit resulteert tijdens het compileren een warning:
    W1057 Implicit string cast from 'ShortString' to 'string'
    Waarom wordt een shortstring in Delphi nog steeds niet gezien als een string? Als je dit zelfde verhaal verwerkt in Lazarus, komt deze zonder warning terug. Klaarblijkelijk wordt daar anders met strings omgegaan.
    Delphi is great. Lazarus is more powerfull

  2. #2
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,377
    Voor zover ik weet zijn shortstrings er alleen nog omwille van backwards compatibility.
    Hieruit leid ik af dat het eigenlijk niet veel zin heeft om deze nog te gebruiken in nieuwe code,
    omdat stringbewerkingsroutines geoptimaliseerd zijn voor "Normale" (Ansi- en UniCode-) strings.

    Dus daar waar je wellicht geheugenruimte (wat kost dat tegenwoordig nog?) spaart, boet je weer
    in snelheid in (denk ik, maar ik maak mij hier eerlijk gezegd nooit druk over).

    Overigens gebruikt voorbeeld 1 maar 11 bytes geheugen wanneer je hem als eigen type zou declareren:
    Delphi Code:
    1. type
    2.   JohnString = string[10];
    3.  
    4.   TFoo = record
    5.     regel1: JohnString;
    6.   end;
    Last edited by VideoRipper; 21-Jan-19 at 16:19.
    TMemoryLeak.Create(Nil);

  3. #3
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    9,948
    "string" is de default stringtype in delphi dus ansistring of unicodestring, afhankelijk van versie.

    FPC is wat gecompliceerde en daar kan het short/ansi/unicodestring zijn, afhankelijk van mode, mogelijk dat daarom de maken warning wat gecompliceerder ligt.

    Zoals Videoripper al zet, er zijn maar weinig reden om shortstring te gebruiken. Lengte beperking, encoding gelijk aan de default windows encoding, en delphi vziw mist een hoop shortstring RTL support, en converteert van en naar ansisstring.

    Het enige voordeel is dat het statisch is, zodat je structures in een slag met blockwrite() of stream.write naar disk kan gooien. Maar zelfs daarvoor is het vrij nutteloos agv de lengte beperking. Dan kan je nog beter een p(ansi)char in een blok geheugen gebruiken.

  4. #4
    Quote Originally Posted by jkuiper View Post
    Dit kan een vertraging oplopen.
    Doe het eens even een miljoen keer, en kijk welke trager is, en of het zoveel uitmaakt dat het je boeit.
    1+1=b

  5. #5
    De andere use-case is file of recordtype.
    Daarin mag geen managed type voorkomen.
    Dat gaat problemen opleveren met Unicode dus...

    Bart

  6. #6
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    9,948
    of lange strings. En als je langere strings hebt zit er een hoop ongebruikte ruimte in. Dus eigenlijk doe ik dat nooit.

    Qua timing verwacht ik dat het lastig is daar een eenduidig antwoord op te geven. Ik heb er wel eens aangetimed, maar het hangt van teveel dingen af:
    - Waar en hoeveel encoding conversies zitten, zowel in string only en shortstring gebruikt.
    - In het shortstring geval of je veel ansistring<>shortstring conversies hebt. Als al je lookup keys unicodestring zijn, maar je key in je collectie shortstring heb je daar weer een conversie te pakken. Dat kan oplopen.
    - Shortstring is zeer gevoelig voor parameters die niet CONST zijn.

    Een van de redenen is dat ik een systeem heb met persistentie van ongeveer een miljoen strings, en die krijg ik niet echt veel sneller geladen dan een dikke seconde. De laadtijd an sich is echter ongeveer een kwart seconde, de rest is unicodestring-->utf8string conversie en datastructuur overhead. (en dat vereist al de gebufferede TFilestream, overigens een aanrader)

    Ik ben met ooit met een nieuwe benadering begonnen van de oude lightcontainer die ik gebruik maar dat is wat op de lange termijn geschoven.

    Het is een generic <string,T> map die intern uit blokken bestaat. In zo'n blok zitten strings gepacked, 2 bytes lengte + char data en een index. De records ook. Index en strings zijn zo dat ze elk met een enkele stream.write geschreven kunnen worden. Encoding conversie gebeurt dan alleen on access (en dat is een O(log) operatie)
    Last edited by marcov; 22-Jan-19 at 10:10.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •