-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add js compiler protodef implementation, that is 10x faster #102
Conversation
That's cool.
Did you try yet to read minecraft protocol.json with this or are there
missing features that prevent it ?
…On Mon, May 11, 2020, 21:57 Karang ***@***.***> wrote:
My attempt at #86 <#86>
For now the compiler can only generate reading code, writing will be done
later. It follows the protodef standard and can be extended with custom
native types. It can compile a code that is able to read the whole nbt spec.
I also included an experimental function that can optimize the generated
code using the closure compiler. It is not always faster and, when it is,
not by much.
Running examples/compiled.js:
Running 1000000 tests
read compiled: 98.29 ms (10173.47k packet/s)
parser: 5061.42 ms (197.57k packet/s)
read compiled (+closure): 79.97 ms (12504.31k packet/s)
Running examples/compiled_nbt.js:
Running 10000 tests
read compiled: 414.75 ms (24.11k packet/s)
parser: 2324.88 ms (4.30k packet/s)
read compiled (+closure): 408.18 ms (24.50k packet/s)
------------------------------
You can view, comment on, or merge this pull request online at:
#102
Commit Summary
- First compiler version
- Refactor compiler
- Add nbt example
File Changes
- *A* examples/bigtest.nbt
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-708b8e0cd839473a86e479bc881a4589>
(0)
- *A* examples/compiled.js
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-5ed6b27e089def914e547cb305c8782d>
(95)
- *A* examples/compiled_nbt.js
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-9e714e61d25d5e6f12b4fcd39795423f>
(140)
- *A* examples/nbt.json
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-cec856c9b6a6b27ffc0b3be07fc46ee4>
(113)
- *M* package.json
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-b9cfc7f2cdf78a7f4b91a753d10865a2>
(1)
- *A* src/compiler.js
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-b0b85d67c2201828828422795fb44581>
(243)
- *M* src/index.js
<https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-1fdf421c05c1140f6d71444ea2b27638>
(1)
Patch Links:
- https://github.com/ProtoDef-io/node-protodef/pull/102.patch
- https://github.com/ProtoDef-io/node-protodef/pull/102.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#102>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAR437U4WNDPLTRG6SEEOJDRRBKBBANCNFSM4M6GOAPQ>
.
|
As far as node-protodef is concerned, nothing is missing. But to implement the minecraft protocol, the specific primitives needs to be implemented : https://github.com/PrismarineJS/node-minecraft-protocol/blob/master/src/datatypes/minecraft.js (nbt is already done in my example). But following the example of https://github.com/ProtoDef-io/node-protodef/pull/102/files#diff-9e714e61d25d5e6f12b4fcd39795423fR64 it shouldn't be hard to do. I included the nbt example here (and copy pasted some code from prismarine-nbt) for testing purpose, but in reality, the non- node-protodef code should be in its respective repository. So, to support minecraft protocol, we need to first update prismarine-nbt then node-minecraft-protocol. (I can already implement the missing bits and include them here for testing, then we can move it later) |
ok I get it, would be good to add a .md file similar to https://github.com/ProtoDef-io/node-protodef/blob/master/doc/newDatatypes.md that would explain how to add these types |
} | ||
|
||
function optimize (code, cb) { | ||
const closureCompiler = new ClosureCompiler({ | ||
language_in: 'ES6', | ||
compilation_level: 'SIMPLE' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm, did 'ADVANCED' mode breaks code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is too aggressive with variable renaming, even when specifying the correct externs. There might be a way to make it work but a lot of configuration would be required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall it looks good
it would be nice to run the tests using it
|
||
## New datatypes | ||
|
||
Like the ProtoDef interpreter, the ProtoDef compiler can be extended with custom datatypes. To register a custom type, use the `addTypes(types)` method of the ProtoDef compiler. The `types` parameter is an object with the following structure: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think of grouping the types (each with its read, write, sizeof) instead of doing groups of read/write/sizeof containing each all the types ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I can do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this was done to simplify the implementation: internally there is 3 separate compilers for each functionality, it's just easier to give them each their own types. We can go around that with a conversion step but that's a bit of work I prefer to do later.
Overall API looks ok, so I think it makes sense to start integrating directly in prismarine-nbt and node-minecraft-protocol (you can git depend on node-protodef for now in PRs) |
would be nice to adapt the unit tests (https://github.com/ProtoDef-io/node-protodef/tree/master/test/dataTypes) and benchmarks (https://github.com/ProtoDef-io/node-protodef/tree/master/benchmark) to run on both the interpreter and the compiler (separately) |
if (!isNaN(fn)) { | ||
this.primitiveTypes[type] = fn | ||
this.native[type] = (value) => { return fn } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we inline native functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case fn is a number (!isNaN(fn)
) It cannot be inline because it needs to have the same function interface, but anyway the JIT compiler will optimise it for us.
done |
LGTM, thanks for this huge improvement ! |
My attempt at #86
The compiler can generate reading and writing code. It follows the protodef standard and can be extended with custom native types. It can compile a code that is able to read the whole nbt spec.
I also included an experimental function that can optimize the generated code using the closure compiler. It is not always faster and, when it is, not by much.
Running
examples/compiled.js
:Running
examples/compiled_nbt.js
: