Skip to content

Instantly share code, notes, and snippets.

@LeopoldTal
Last active April 17, 2021 22:57
Show Gist options
  • Save LeopoldTal/5df9ada73064d73fe843e103a42181e9 to your computer and use it in GitHub Desktop.
Save LeopoldTal/5df9ada73064d73fe843e103a42181e9 to your computer and use it in GitHub Desktop.
Inform string benchmark

Simple string truncation benchmark

Motivation

Inform seems rather lacking in string manipulation utilities: There doesn't seem to be any way to slice a string, nor any way to change one in place except by match replacement.

As a result, it's unclear what the best way to truncate a string is. This story file is a simple benchmark for 6 different methods:

  • building the new string character-by-character from the start
  • copying the string then erasing the extra characters left-to-right
  • snipping a copy of the string from the end
  • matching the first N characters with a regular expression
  • copying the string then writing a null byte at the desired end (in Inform 6)
  • writing a null byte at the desired end, modifying the string in-place (in Inform 6)

Results

Short text

Evaluating all methods by truncating a 1162-char string to 581 chars.

Interpreter Copying from start Snipping LTR Snipping RTL Regex Inform6 with copy Inform6 in place
Quixe+Safari 4.88 s 7.62 s 7.47 s < 50 ms < 50 ms < 50 ms
Quixe+Firefox 8.75 s 15.1 s 14.8 s 62 ms < 50 ms < 50 ms
Gargoyle 875 ms 1.31 s 1.34 s < 50 ms < 50 ms < 50 ms
Lectrote 4.19 s 6.81 s 6.72 s 62 ms < 50 ms < 50 ms
Spatterlight 4.91 s 7.81 s 8.28 s < 50 ms < 50 ms < 50 ms

Long text

Evaluating the fastest methods by truncating a 32432-char string to 16216 chars.

Interpreter Regex Inform6 with copy Inform6 in place
Quixe+Safari 937 ms 250 ms 187 ms
Quixe+Firefox 1.66 s 343 ms 343 ms
Gargoyle 125 ms 62 ms < 50 ms
Lectrote 875 ms 187 ms 125 ms
Spatterlight 906 ms 218 ms 187 ms
"String benchmark" by Leopold Tal
The story headline is "A simple benchmark for string truncation".
The story genre is "Other".
The release number is 1.
The story description is "Truncates a string in different ways and times each method."
The story creation year is 2021.
Release along with an interpreter.
There is a room.
[Ignoring high seconds, so benchmarks over the Y2038 rollover will be wrong.]
To decide what number is the second: (- GetTimeComponent(1) -).
To decide what number is the microsec: (- GetTimeComponent(2) -).
To decide what real number is the current time:
let hoursec be remainder after dividing second by 864000; [breaks at boundaries, but rounding errors suck]
decide on (hoursec + (0.000001 * microsec)).
Include (-
Array countofseconds --> 3;
[ GetTimeComponent n;
if (glk($0004, 20, 0) == 0) return 0; ! glk_gestalt_DateTime(20, 0);
glk($0160, countofseconds); ! glk_current_time(timeval);
return countofseconds-->n;
];
-) after "Definitions.i6t".
To decide what text is the truncation of (S - text) to (N - number) characters by copying at start:
let result be a text;
repeat with charnum running from 1 to N:
now result is "[result][character number charnum in S]";
decide on result.
To decide what text is the truncation of (S - text) to (N - number) characters by snipping ltr:
let truncated be S;
now N is N plus 1; [fucken one-indexing]
let initial length be the number of characters in S;
repeat with charnum running from N to initial length:
replace character number N in truncated with "";
decide on truncated.
To decide what text is the truncation of (S - text) to (N - number) characters by snipping rtl:
let truncated be S;
let charnum be the number of characters in S;
while charnum is greater than N:
replace character number charnum in truncated with "";
decrease charnum by 1;
decide on truncated.
To decide what text is the truncation of (S - text) to (N - number) characters by regex:
if S matches the regular expression "^.{0,[N]}":
decide on text matching regular expression;
otherwise:
say "BUG: [S] did not match an expression that should match anything."
Include (-
[ TruncateText txt max_len;
TEXT_TY_Transmute(txt);
if (max_len > TEXT_TY_CharacterLength(txt)) {
return;
}
BlkValueWrite(txt, max_len, 0);
];
-)
To decide what text is the truncation of (S - text) to (N - number) characters by i6:
let T be S;
truncate T in place to N characters;
decide on T.
To truncate (T - text) in place to (N - number) characters:
(- TruncateText({-lvalue-by-reference:T}, {N}); -)
Input is always "Now the whole earth had one language and the same words. And as people migrated from the east, they found a plain in the land of Shinar and settled there. And they said to one another, 'Come, let us make bricks, and burn them thoroughly.' And they had brick for stone, and bitumen for mortar. Then they said, 'Come, let us build ourselves a city and a tower with its top in the heavens, and let us make a name for ourselves, lest we be dispersed over the face of the whole earth.' And the Lord came down to see the city and the tower, which the children of man had built. And the Lord said, 'Behold, they are one people, and they have all one language, and this is only the beginning of what they will do. And nothing that they propose to do will now be impossible for them. Come, let us go down and there confuse their language, so that they may not understand one another's speech.' So the Lord dispersed them from there over the face of all the earth, and they left off building the city. Therefore its name was called Babel, because there the Lord confused the language of all the earth. And from there the Lord dispersed them over the face of all the earth."
Target-length is always 581.
Expected is always "Now the whole earth had one language and the same words. And as people migrated from the east, they found a plain in the land of Shinar and settled there. And they said to one another, 'Come, let us make bricks, and burn them thoroughly.' And they had brick for stone, and bitumen for mortar. Then they said, 'Come, let us build ourselves a city and a tower with its top in the heavens, and let us make a name for ourselves, lest we be dispersed over the face of the whole earth.' And the Lord came down to see the city and the tower, which the children of man had built. And the L".
When play begins:
let in-place be input;
let tick0 be the current time;
let by-copying be the truncation of input to target-length characters by copying at start;
let tick1 be the current time;
let by-snipping-ltr be the truncation of input to target-length characters by snipping ltr;
let tick2 be the current time;
let by-snipping-rtl be the truncation of input to target-length characters by snipping rtl;
let tick3 be the current time;
let by-regex be the truncation of input to target-length characters by regex;
let tick4 be the current time;
let by-i6 be the truncation of input to target-length characters by i6;
let tick5 be the current time;
truncate in-place in place to target-length characters;
let tick6 be the current time;
say validation for by-copying as "Copying from start" from tick0 to tick1;
say validation for by-snipping-ltr as "Snipping LTR" from tick1 to tick2;
say validation for by-snipping-rtl as "Snipping RTL" from tick2 to tick3;
say validation for by-regex as "Regex" from tick3 to tick4;
say validation for by-i6 as "Inform6 with copy" from tick4 to tick5;
say validation for in-place as "Inform6 in place" from tick5 to tick6;
say "Done.";
quit.
To say validation for (actual - a text) as (varname - a text) from (tic - a real number) to (toc - a real number):
if actual is expected:
let elapsed be toc minus tic;
say "[varname]: OK, done in [elapsed] seconds.";
otherwise:
say "[varname] does not match expected: has [number of characters in actual], should have [number of characters in expected].";
say "Expected:[line break]";
say expected;
say line break;
say "Actual:[line break]";
say actual;
say paragraph break.
To quit: (- quit; -)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment