Open GoogleCodeExporter opened 9 years ago
I do not want to copy VX optimizator functional theoretically.
And why? Obfuscation?
> This would be ofc after you fix the current bugs = )
Agree. We return to this issue later.
Original comment by adi...@gmail.com
on 12 Aug 2011 at 4:43
Oh, the reason is for optimization.
Variables/Functions/Etc with smaller names run faster. Reading/Setting a var
named xxxxxxxxxxxxxx is much slower than reading/setting a var named x.
Original comment by mrasolo...@gmail.com
on 12 Aug 2011 at 4:57
> Reading/Setting a var named xxxxxxxxxxxxxx is much slower than
reading/setting a var named x.
What?! It's "delirium"!
Ok, I know one russian hacker. Remember 1.23 version and expolit with code
executing? This is his handiwork. And he give to me some tool - wc3 jass code
disassembler. So, when map selected in game menu all code parsed into jass
pseudocode. It is disassembled listing:
{{{
086F87F0 BJDebugMsg+0000 00 01 06 08 000009c0 CREATE_LOCAL_FROM_STACK msg
[1] {string (6)}
086F87F8 BJDebugMsg+0008 00 00 04 05 0000005c CREATE_LOCAL i {integer (4)}
086F8800 BJDebugMsg+0010 00 04 ba 0c 00000000 MOV_VAL_REG 0 => #ba {integer
(4)}
086F8808 BJDebugMsg+0018 00 00 ba 11 0000005c MOV_REG_VAR #ba => i
086F8810 BJDebugMsg+0020 00 00 00 28 00000001 STUB_LOOP main
086F8818 BJDebugMsg+0028 00 04 bb 0e 0000005c MOV_VAR_REG i => #bb {integer
(4)}
086F8820 BJDebugMsg+0030 00 00 bb 13 00000000 PUSH #bb
086F8828 BJDebugMsg+0038 00 00 00 15 00000530 CALL_NATIVE Player
086F8830 BJDebugMsg+0040 00 00 00 13 00000000 PUSH #00
086F8838 BJDebugMsg+0048 00 04 bc 0c 00000000 MOV_VAL_REG 0 => #bc {integer
(4)}
086F8840 BJDebugMsg+0050 00 00 bc 17 00000000 #bc = (float)#bc
086F8848 BJDebugMsg+0058 00 00 bc 13 00000000 PUSH #bc
086F8850 BJDebugMsg+0060 00 04 bd 0c 00000000 MOV_VAL_REG 0 => #bd {integer
(4)}
086F8858 BJDebugMsg+0068 00 00 bd 17 00000000 #bd = (float)#bd
086F8860 BJDebugMsg+0070 00 00 bd 13 00000000 PUSH #bd
086F8868 BJDebugMsg+0078 00 04 be 0c 0000003c MOV_VAL_REG 60 => #be
{integer (4)}
086F8870 BJDebugMsg+0080 00 00 be 17 00000000 #be = (float)#be
086F8878 BJDebugMsg+0088 00 00 be 13 00000000 PUSH #be
086F8880 BJDebugMsg+0090 00 06 bf 0e 000009c0 MOV_VAR_REG msg => #bf
{string (6)}
086F8888 BJDebugMsg+0098 00 00 bf 13 00000000 PUSH #bf
086F8890 BJDebugMsg+00A0 00 00 00 15 000005fe CALL_NATIVE
DisplayTimedTextToPlayer
086F8898 BJDebugMsg+00A8 00 04 c0 0e 0000005c MOV_VAR_REG i => #c0 {integer
(4)}
086F88A0 BJDebugMsg+00B0 00 00 c0 13 00000000 PUSH #c0
086F88A8 BJDebugMsg+00B8 00 04 c1 0c 00000001 MOV_VAL_REG 1 => #c1 {integer
(4)}
086F88B0 BJDebugMsg+00C0 00 00 c2 14 00000000 POP #c2
086F88B8 BJDebugMsg+00C8 c1 c2 c2 20 00000000 #c2 = #c2 + #c1
086F88C0 BJDebugMsg+00D0 00 00 c2 11 0000005c MOV_REG_VAR #c2 => i
086F88C8 BJDebugMsg+00D8 00 04 c3 0e 0000005c MOV_VAR_REG i => #c3 {integer
(4)}
086F88D0 BJDebugMsg+00E0 00 00 c3 13 00000000 PUSH #c3
086F88D8 BJDebugMsg+00E8 00 04 c4 0e 0000080a MOV_VAR_REG bj_MAX_PLAYERS =>
#c4 {integer (4)}
086F88E0 BJDebugMsg+00F0 00 00 c5 14 00000000 POP #c5
086F88E8 BJDebugMsg+00F8 c4 c5 c5 1a 00000000 #c5 = (#c5 == #c4)
086F88F0 BJDebugMsg+0100 00 00 c5 29 00000002 IF (#c5) THEN JUMP
BJDebugMsg+0x0118
086F88F8 BJDebugMsg+0108 00 00 00 2b 00000001 JUMP BJDebugMsg+0x0028
086F8900 BJDebugMsg+0110 00 00 00 28 00000002 STUB_LOOP event
086F8908 BJDebugMsg+0118 00 00 00 27 00000000 RETURN
086F8910 BJDebugMsg+0120 00 00 00 04 00000000 STUB_FUNC_END
}}}
So, as you see all jass instructions is 8 bytes opcodes. Name of variables is't
used at all.
Original comment by adi...@gmail.com
on 12 Aug 2011 at 5:13
It was benched at wc3c and proven. The benchmark showed a few ms in difference.
Also, it was proven in my initial version of TimerQueue. The variable names
were almost 3 lines long and the system lagged terribly relative to native
timers. When the variable names were shortened to a minimal amount, the
performance drastically increased.
It has been benched and documented and encountered ; P. The wc3 community now
accepts the fact that longer names means slower code.
Original comment by mrasolo...@gmail.com
on 12 Aug 2011 at 5:25
Ok, for the bench, function calls weren't tested, only variables. It could be
that function names don't matter but variable names do ;\.
Dr Super Good thinks that they might be doing character by character for look
ups on variables.
Original comment by mrasolo...@gmail.com
on 13 Aug 2011 at 7:17
> but variable names do ;\.
086F88D8 BJDebugMsg+00E8 00 04 c4 0e 0000080a MOV_VAR_REG bj_MAX_PLAYERS =>
#c4 {integer (4)}
It use only dword - pointer to variable.
Give me your bench map, I look it.
Length of the variable name can only affect to the speed of parsing maps code,
and very little.
Original comment by adi...@gmail.com
on 13 Aug 2011 at 7:54
I can't link you the thread with the benchmark on it since wc3c is down.
When wc3c comes back up (who knows when), go to resources section and
submissions and go to the old Timer Queue thread. Scroll down and you'll
eventually find a reply that has benches on it.
And yes, in Timer Queue, it originally ran slower than natives timers and the
variable names were like 3 lines long. When I made the variable names very
short (a few characters), it's speed drastically increased and it became much
faster than natives ;p.
Considering the only thing I changed between the two things was the variable
names, it stands to reason that longer variable names are slower for JASS to
process.
People complained about the short variable names in TimerQueue when I submitted
it. I told them the above, and like you, nobody believed me. Nobody on any site
believed me actually, and most people still don't believe it and regard it as
bs.
The first proper benchmark of it was conducted at wc3c on the TimerQueue thread
using RtC natives. The benchmark showed that my assertions were in fact correct
and people stopped arguing with me about speeds based on variable name length.
If you look around thw, some people are following the practice of variable
names that are as short as possible (1-2 characters) in order to keep their
script running as fast as possible (I was first person to start that trend).
This practice is now becoming a problem as scripts are becoming largely
unreadable.
If cjass had slimmed labels down to minimal sizes, people would stop this
practice and depend on cjass optimizer instead and we wouldn't have our current
issues of unreadable code.
You're our only hope ; P. It looks like vex's renaming in his map optimizer
will never be fixed, meaning that the short var name practice will likely
continue on until someone comes up with a solution.
I didn't suggest this all willy nilly. I suggested it as a solution to a
current and very serious problem that is current resulting in piles of
completely unreadable code.
Here is just one example
loop
exitwhen not lb[n]
loop
exitwhen not lb[n] or (0==rl[n] and 0==rh[n]) or 0==n
set y=dm[this].depthPointer
loop
exitwhen not lb[y.depthNode]
set y=y.depthPointer
endloop
exitwhen (y.id>=rl[n] and y.id<=rh[n])
set n=dm[this].skip
endloop
if (lb[n]) then
if (0!=li[n]) then
set l=n
endif
set n=dm[this].get
endif
endloop
Original comment by mrasolo...@gmail.com
on 13 Aug 2011 at 9:02
Oh, and another good optimizer practice is to fix all comparisons to 0 so that
the 0 is in front
For example
if (this==0) then
should turn into
if (0==this) then
The 0 in front is faster than the 0 behind. I don't know why, it's a weird JASS
thing. It only works with 0 as well (it might actually work with 1 too, haven't
tested 1).
This is faster
if (0==55) then
than this
if (55==0) then
So that should be semi simple.. find all ==0 and flip it. Also, for like if
this > 0, you can flip to 0<this.
Also, get rid of as many <= and >= as you can. >= and <= are about half the
speed of <, >, !=, and ==.
Original comment by mrasolo...@gmail.com
on 13 Aug 2011 at 9:05
And dude, I'm an optimizer freak. I know all of the ins and outs of JASS ; P
(tricks etc for speed increases).
Original comment by mrasolo...@gmail.com
on 13 Aug 2011 at 9:06
I guess to shorten var names via an external program wouldnt be that hard, but
I have to agree, that it would be nice to be included in the adic optimizer.
Original comment by erwgfifo...@gmail.com
on 13 Aug 2011 at 9:31
> And dude, I'm an optimizer freak.
I'm too. We must have two codes - first readable to users, and second fast to
executing.
{{{
For example
if (this==0) then
should turn into
if (0==this) then
}}}
May be) Ok, I need 22 patch to launch my secret tool;) Also we're test
variables name processing.
Original comment by adi...@gmail.com
on 13 Aug 2011 at 11:45
{{{
nothing fx () {
boolean b
b = 0 == 55
b = 55 == 0
}
}}}
08B9D3F8 fx+0020 00 00 00 03 00000e9f STUB_FUNC_BEGIN fx
08B9D400 fx+0000 00 00 08 05 000005f3 CREATE_LOCAL b {boolean (8)}
// 0 == 55
08B9D408 fx+0008 00 04 ca 0c 00000000 MOV_VAL_REG 0 => #ca {integer (4)}
08B9D410 fx+0010 00 00 ca 13 00000000 PUSH #ca
08B9D418 fx+0018 00 04 cb 0c 00000037 MOV_VAL_REG 55 => #cb {integer (4)}
08B9D420 fx+0020 00 00 cc 14 00000000 POP #cc
08B9D428 fx+0028 cb cc cc 1a 00000000 #cc = (#cc == #cb)
// result to b
08B9D430 fx+0030 00 00 cc 11 000005f3 MOV_REG_VAR #cc => b
// 55 ==0
08B9D438 fx+0038 00 04 cd 0c 00000037 MOV_VAL_REG 55 => #cd {integer (4)}
08B9D440 fx+0040 00 00 cd 13 00000000 PUSH #cd
08B9D448 fx+0048 00 04 ce 0c 00000000 MOV_VAL_REG 0 => #ce {integer (4)}
08B9D450 fx+0050 00 00 cf 14 00000000 POP #cf
08B9D458 fx+0058 ce cf cf 1a 00000000 #cf = (#cf == #ce)
// resule t b
08B9D460 fx+0060 00 00 cf 11 000005f3 MOV_REG_VAR #cf => b
// retn
08B9D468 fx+0068 00 00 00 27 00000000 RETURN
08B9D470 fx+0070 00 00 00 04 00000000 STUB_FUNC_END
Any difference.
adic3x 15:06:25 Тут типы утверждают, что чем
короче имя переменной - тем быстрее к ней
обращение.
cr*** 15:06:36 нахуй пусть идут
cr*** 15:08:28 даешь им ИДу
cr*** 15:08:32 даешь им гейм.длл
cr*** 15:08:35 и говоришь = докажите
Original comment by adi...@gmail.com
on 13 Aug 2011 at 12:28
Well, I've done some benchmarks (on 1.24.4.6387) with this code:
#include "lib\\cj_types.j"
#define VAR_NAME = a
#define COUNT = 24576
int VAR_NAME
callback onInit () {
TimerStart (CreateTimer(), 3.0, true, lambda nothing () {
int sw = StopWatchCreate()
float mark = StopWatchMark(sw)
#repeat COUNT
VAR_NAME = 0
#endrepeat
mark = (StopWatchMark(sw) - mark) * 1000.0
BJDebugMsg(R2S(mark))
})
}
and got following results:
2,09..2,14 - "a" (1)
2,50..2,55 - "aaaaa" (5)
2,96..3,01 - "aaaaaaaaaa" (10)
4,25..4,30 - "aaaaaaaaaaaaaaa" (15)
Also, I've tried to test 20 char length variable name, but jasshelper failed at
compilation.
Original comment by shadow.d...@gmail.com
on 13 Aug 2011 at 12:49
Can't be ... Blizz never cease to amaze me!) Ok, issue accapted.
Original comment by adi...@gmail.com
on 13 Aug 2011 at 1:03
Original comment by adi...@gmail.com
on 24 Aug 2011 at 6:18
Original issue reported on code.google.com by
mrasolo...@gmail.com
on 11 Aug 2011 at 8:29