delphi - How can I extract part of a PChar into a string? -


during profiling came across function taking quite bit of time, boiled down simple piece of code:

function getsubstring(ainput: pchar; astart, asubstringlength: integer): string; begin   result := copy(ainput, astart, asubstringlength); end; 

this function returns expected sub-string, doesn't scale longer inputs. looked @ assembler code in cpu view, , can tell (i'm not working @ assembler level), seems ainput implicitly converted string before calling copy.

but since @ point length of string/character array unknown, conversion code has walk length of pchar until finds null terminator. explain terrible scaling longer inputs.

however, since caller passes in length of pchar, thought convert method use setstring instead.

function getsubstring(ainput: pchar; astart, asubstringlength: integer): string; begin   setstring(result, ainput + astart - 1, asubstringlength); end; 

in addition setstring working zero-based (not one-based copy), there seem number of other little things copy in terms of validating inputs, not of documented (e.g. start value less 1 changed 1). naïve implementation above doesn't work original one.

my goal replicate copy routine as possible, function part of library , has been used extensively colleagues.

i'm wondering whether following implementation accomplishes that, or whether need aware of other caveats of copy. nb: flength actual length of ainput comes part in module function part of. removed other part example.

function getsubstring(ainput: pchar; astart, asubstringlength: integer): string; begin   if (ainput = nil) begin     result := '';   end else begin     if (astart < 1) begin       astart := 0;     end else begin       astart := astart - 1;     end;     if (asubstringlength + astart > flength) begin       asubstringlength := flength - astart;     end;     setstring(result, ainput + astart, asubstringlength);   end; end; 

i'm using delphi 2006, assume isn't different in other versions of product (at least non-unicode ones).

let's consider corner cases. think are:

  1. ainput invalid.
  2. astart < 1.
  3. astart > flength.
  4. asubstringlength < 0.
  5. asubstringlength + (astart-1) > flength.

we can ignore case 1 in opinion. onus should on caller provide valid pchar. indeed check ainput <> nil step far in view because nil not valid pchar.

of rest have covered 2 , 5, not 3 , 4. if user supplies value of astart large, read off end of string. likewise, user can readily supply negative asubstringlength. don't think need write code check these cases since competent.

now, if care every last drop of performance, should not checking of these case. demand user passes valid parameters. in debug mode, {$ifopf d+} or assert might check inputs. of course, if these arguments come external sources, should validated.

on other hand, biggest performance hit original code suffers needless scanning of entire string, , copying intermediate heap allocated string. once you've removed those, have, opportunity further performance gains reduced.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -