• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

How to speed JassHelper (vJass) with 1 line of code

Status
Not open for further replies.
Level 13
Joined
Nov 7, 2014
Messages
571
The following functions: DoJASSerStructMagic, DoJASSerInlineMagicF, DoJASSerShadowHelperMagicF, and DoJASSerReturnFixMagicF (in file jasshelper.pas) look pretty much the same:

Code:
procedure DoJASSerStructMagic(f1:string;f2:string;const debug:boolean);overload;
var
   ff2:textfile;
   bff2:boolean;
   i,o:string;
begin

    bff2:=false;
    try
        LoadFile(f1,i);
        DoJASSerStructMagic(i,debug,o);

        AssignFile(ff2,f2);bff2:=true;

        filemode:=fmOpenWrite;
        Rewrite(ff2);
        Write(ff2,o);
    finally

        if(bff2) then Close(ff2);
    end;
end;

First, the whole content of the file ('currentmapscript.j') is read, then some magic is done with it (DoXXXMagic(...)), and the result of the "magic" is written to another file ('outputwar3map.j').
For the writing of the 'outputwar3map.j' file, the 'TextFile' type and the functions: 'AssignFile', 'Rewrite', 'Write' and 'Close' are used.
The problem is that 'TextFile's have tiny buffers by default (128 bytes), and writing a lot of bytes using a tiny buffer results in a lot of 'WriteFile' system calls (assuming windows), which is inefficient.

An easy fix would be to add a call to SetTextBuf with a buffer of size > 128 (65536 maybe?) after the call to 'Rewrite(ff2)'.
 
Level 20
Joined
Jan 3, 2022
Messages
364
Did you run any benchmarks? Assume 600 KB of code. 128 bytes: 4800 calls. 16384 bytes: 38 calls.

Bash:
# This writes 600KB of text to console, in 128 bytes or 16KB pieces
$ time lua -e 'math.randomseed(42);local total=600*1024;local buf=128 for i = 1, math.ceil(total/buf) do io.stdout:write(string.char(math.random(32,126)):rep(buf)) end' > /dev/null

# vs

time lua -e 'math.randomseed(42);local total=600*1024;local buf=16384 for i = 1, math.ceil(total/buf) do io.stdout:write(string.char(math.random(32,126)):rep(buf)) end' > /dev/null
There's practically no speed difference, the process launch takes so much time it's impossible to determine any difference.
 
Status
Not open for further replies.
Top