• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

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 19
Joined
Jan 3, 2022
Messages
320
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