Thanks very much for the explanation. What you show as original source code could ideed be efficient. As you can see the obfuscator completely destroys this. So I wonder how much of a slowdown the obfuscation causes.
You seem to assume the size of the hash entry is 14 byte. But how should the JavaScript know that any of the this.depth, this.flags... can be smaller than a normal 32-bit integer? I would have expected a size of 6x4 = 24 byte fir the data you store. And the brd_HashTable array probably contains a pointer (4 or 8 additional bytes?) to the object itself.
I don't know if even storing a simple integer would not require more than 4 byte in JavaScript, because it has to remember somewhere that it is an integer too (as JavaScript allows it to be anything else).
tomitankChess - New JavaScript engine
Moderators: hgm, Rebel, chrisw
-
- Posts: 27825
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: tomitankChess - New JavaScript engine
None, if my memory is correct. From what I remember 'var["key"] = value' and 'var.key = value' are equivalent constructs in JavaScript (so it may look like a struct, but it's really a hash). That may even be the case for arrays, but don't take my word for it. I looked into it a while back to see if it would be doable to port SjaakII to JavaScript, but I didn't do much with it in the end.hgm wrote:Thanks very much for the explanation. What you show as original source code could ideed be efficient. As you can see the obfuscator completely destroys this. So I wonder how much of a slowdown the obfuscation causes.
Long story short: JavaScript was not meant to be used for high performance computing...
-
- Posts: 276
- Joined: Sat Mar 04, 2017 12:24 pm
- Location: Hungary
Re: tomitankChess - New JavaScript engine
Almost. The non multiple arrays bit faster in JavaScript.Evert wrote: From what I remember 'var["key"] = value' and 'var.key = value' are equivalent constructs in JavaScript.
Eg: array declaration mode in JavaScript is very important for speed.
https://stackoverflow.com/questions/931 ... ascript-ar
It's tricky, but this depends on the browser. Node.js can give you another result. (Unfortunately.)
Yes. I hope my engine will be around 2500 Elo (maybe 2600).Evert wrote: Long story short: JavaScript was not meant to be used for high performance computing...
Of course with pure JavaScript.
-
- Posts: 27825
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: tomitankChess - New JavaScript engine
But there is a big difference between var["key"] and var[variable], in that even when it is a hash table, the index can be precomputed in the former, but has to be calculated at run time in the latter.
I remember the early days of micro-computer BASIC, and some of those did a linear search through the symbol table for "X" whenever they encountered a statement "X = 0". These BASICs were of course slow as hell, and were quickly replaced by versions that would do the lookup only when you entered the statement, and then stored the the address of the storage assigned to X with the statement. In other words, they were ot strict interpreters, but they pre-compiled the BASIC statemets to some intermediate 'bcode', which can be efficiently interpreted.
I suppose that for JavaScript we have long since made that transition. It would be very sad indeed when this was not the case. Because that would mean I, as an amateur, could write a JavaScript interpreter that would be about two orders of magnitude faster than Google's node.exe.
And the point is that var[variable] cannot be pre-compiled, as the value of 'variable' at run time could be different from that at compile time.
I remember the early days of micro-computer BASIC, and some of those did a linear search through the symbol table for "X" whenever they encountered a statement "X = 0". These BASICs were of course slow as hell, and were quickly replaced by versions that would do the lookup only when you entered the statement, and then stored the the address of the storage assigned to X with the statement. In other words, they were ot strict interpreters, but they pre-compiled the BASIC statemets to some intermediate 'bcode', which can be efficiently interpreted.
I suppose that for JavaScript we have long since made that transition. It would be very sad indeed when this was not the case. Because that would mean I, as an amateur, could write a JavaScript interpreter that would be about two orders of magnitude faster than Google's node.exe.
And the point is that var[variable] cannot be pre-compiled, as the value of 'variable' at run time could be different from that at compile time.
-
- Posts: 276
- Joined: Sat Mar 04, 2017 12:24 pm
- Location: Hungary
Re: tomitankChess - New JavaScript engine
The integer can bigger than 32 bit, but not "compatible" with bitwise operators.But how should the JavaScript know that any of the this.depth, this.flags... can be smaller than a normal 32-bit integer?
The Number.MAX_SAFE_INTEGER constant represents the maximum safe integer in JavaScript ((2^53) - 1).
108 bit /14 Byte/ This is the maximal size.
Eg:
this.flags = flags; // 2 bit (0, 1, 2, 3)
this.depth = depth; // 7 bit (max depth is 64) etc..
Did you ask this?
Last edited by tomitank on Fri Sep 22, 2017 2:25 pm, edited 2 times in total.
-
- Posts: 276
- Joined: Sat Mar 04, 2017 12:24 pm
- Location: Hungary
Re: tomitankChess - New JavaScript engine
if variable is not a global variable and it changes then it's true.And the point is that var[variable] cannot be pre-compiled, as the value of 'variable' at run time could be different from that at compile time.
-
- Posts: 27825
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: tomitankChess - New JavaScript engine
What I asked is how the JavaScript interpreter can know that (say) this.flags needs only two bits. You know that, and you write behind the '//', but the '//' starts a comment that is completely ignored by the interpreter, right? Do you specify that anywhere else in your source code?tomitank wrote:The integer can bigger than 32 bit, but not "compatible" with bitwise operators.But how should the JavaScript know that any of the this.depth, this.flags... can be smaller than a normal 32-bit integer?
108 bit /14 Byte/ This is the maximal size.
Eg:
this.flags = flags; // 2 bit (0, 1, 2, 3)
this.depth = depth; // 7 bit (max depth is 64) etc..
Did you ask this?
If not, how is the interpreter to know that flags can only be 0, 1, 2 or 3? As far as it is concerned it might sometimes be a million, or 3 billion. In JavaScript it might even be a text string, "tomitankChess" which would require 13 bytes by itself. I am pretty sure that in JavaScript storing an integer 3 will take up just as many bytes as storing the integer 987654321 (although probably fewer bytes than storing "tomitankChess").
-
- Posts: 276
- Joined: Sat Mar 04, 2017 12:24 pm
- Location: Hungary
Re: tomitankChess - New JavaScript engine
I get it now!
From: https://www.w3schools.com/js/js_numbers.asp
"JavaScript Numbers are Always 64-bit Floating Point
Unlike many other programming languages, JavaScript does not define different types of numbers, like integers, short, long, floating-point etc.
JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard.
This format stores numbers in 64 bits, where the number (the fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and the sign in bit 63"
// comment only for me : )
I don't want to go beyond 28 mb
From: https://www.w3schools.com/js/js_numbers.asp
"JavaScript Numbers are Always 64-bit Floating Point
Unlike many other programming languages, JavaScript does not define different types of numbers, like integers, short, long, floating-point etc.
JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard.
This format stores numbers in 64 bits, where the number (the fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and the sign in bit 63"
// comment only for me : )
I don't want to go beyond 28 mb
-
- Posts: 27825
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: tomitankChess - New JavaScript engine
Well, that would mean that your HashEntry object is at least 6 x 64 = 384 bits (6 x 8 = 48 bytes). I don't know if it still needs extra storage to indicate that the property currently is a number (rather than a text string or an array). I guess floating point codes have enough invalid bit patterns to indicate such things with the number itself. (So a valid IEEE 8-byte floating-point code would mean it is a number, and various invalid codes could indicate null, undefined, NaN, string, array/object...)
It also means that JavaScript does not have any 64-bit integers at all (and not just no logical bit operators for those). In the FP format integers larger than the mantisse (52 bits, IIRC) canot be represented exactly, but would have to be rounded up to various powers of 2.
It should still be possible to do a hash key as a single variable, if you are satisfied with 52 bits, by using an additive key rather than an XOR key (and using 52-bit zobrist keys), as + and - do not suffer from the restriction that their operads are first converted to 32-bit it, as + and - are perfectly defied between FP numbers. Deriving the index from the lowest 20 bits (by ANDing with HASHMASK) and storing the whole number in the HashEntry as signature would give you access to the upper 32 bit of the mantisse.
It also means that JavaScript does not have any 64-bit integers at all (and not just no logical bit operators for those). In the FP format integers larger than the mantisse (52 bits, IIRC) canot be represented exactly, but would have to be rounded up to various powers of 2.
It should still be possible to do a hash key as a single variable, if you are satisfied with 52 bits, by using an additive key rather than an XOR key (and using 52-bit zobrist keys), as + and - do not suffer from the restriction that their operads are first converted to 32-bit it, as + and - are perfectly defied between FP numbers. Deriving the index from the lowest 20 bits (by ANDing with HASHMASK) and storing the whole number in the HashEntry as signature would give you access to the upper 32 bit of the mantisse.
-
- Posts: 276
- Joined: Sat Mar 04, 2017 12:24 pm
- Location: Hungary
Re: tomitankChess - New JavaScript engine
Good idea! 52 bit is relativ safe.If you are satisfied with 52 bits, by using an additive key rather than an XOR key (and using 52-bit zobrist keys)
I thought about it, but can the difference be measured? (Must be measured.)
true!Well, that would mean that your HashEntry object is at least 6 x 64 = 384 bits (6 x 8 = 48 bytes).
Lozza optimize this with V8 typed arrays, but Lozza not running some mobil browser (because of V8 arrays)
More: http://thibaultlaurens.github.io/javasc ... ine-works/