| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
pojo?
Sorry, something went wrong.
There was a problem hiding this comment.
plain old javascript object ... comes from plain old java object, maybe that's just for us old java dogs
Sorry, something went wrong.
There was a problem hiding this comment.
I'll just call it 'object' since it's not obvious
Sorry, something went wrong.
|
Not sure if it matters, but it might be nice to have one for m = Object.create(null), too. |
Sorry, something went wrong.
|
ok, s/pojo/object and added one for a null-prototype object es/map-bench.js method="object" millions="10": 1.07722 es/map-bench.js method="nullProtoObject" millions="10": 1.04962 es/map-bench.js method="fakeMap" millions="10": 0.88726 es/map-bench.js method="map" millions="10": 1.78555 |
Sorry, something went wrong.
|
Should this utilize common.v8ForceOptimization()? |
Sorry, something went wrong.
There was a problem hiding this comment.
I think we're still preferring var over let.
Sorry, something went wrong.
|
s/let/var, thanks for pointing that out. I don't know if this is a candidate for common.v8ForceOptimization() or not, there's a bit of state to pass around, it'd at least be passing in m to optimized functions from the parent bench functions, would that make a difference? |
Sorry, something went wrong.
|
I'll defer to someone with more experience working on the benchmarks, but es/restparams-bench.js, for example, forces optimization with arguments. |
Sorry, something went wrong.
|
AFAIK that should be (million) ops/sec, so technically Map would be the fastest (largest value). That's quite surprising. |
Sorry, something went wrong.
|
Interesting! Map is definitely showing to be faster... even if you take creation of the Map into consideration on each loop. Unmodified version: ~/node/main/node [check] $ ./node benchmark/es/map-bench.js es/map-bench.js method="object" millions="10": 0.84279 es/map-bench.js method="nullProtoObject" millions="10": 0.84733 es/map-bench.js method="fakeMap" millions="10": 0.69652 es/map-bench.js method="map" millions="10": 1.71819 Modified to include map creation on each loop: ~/node/main/node [check] $ ./node benchmark/es/map-bench.js es/map-bench.js method="object" millions="10": 0.77879 es/map-bench.js method="nullProtoObject" millions="10": 0.77240 es/map-bench.js method="fakeMap" millions="10": 0.37927 es/map-bench.js method="map" millions="10": 1.61652 |
Sorry, something went wrong.
|
ok then, that is interesting and explains why fakeMap looked "better" than the pojo, perhaps we go ahead and migrate headers to a Map eh? |
Sorry, something went wrong.
|
@rvagg That would probably have to happen at least in v7 or later since that would be a pretty big change. |
Sorry, something went wrong.
|
The number should be the higher the better? |
Sorry, something went wrong.
|
@simonkcleung Yes. Values are always operations per second. |
Sorry, something went wrong.
|
Moving the querystring and headers objects to Maps definitely makes sense given the perf results but @Fishrock123 is right about targeting such a change for v7. We can likely go ahead and get that change landed in master now as a semver-major. |
Sorry, something went wrong.
There was a problem hiding this comment.
Are we trying to set the same two properties ('i10000000' and 's10000000') 10 million times? If so, maybe use keys like 'a', 'b'. Or should the keys be 'i' + i and 's' + i?
Sorry, something went wrong.
|
@rvagg Thanks for putting this together. When we're using named keys o[key] on an object, access is usually megamorphic. V8 only has limited space in the megamorphic IC stub cache, around 2500 entries. The same cache is used for all megamorphic ICs, which can be completely unrelated to o. Every time we add a property to an object, we create a new transition map. Only if we add properties in exactly the same order can we reuse the maps. This is often not the case, for example when we parse request headers into _headers[key]. Because we need to keep track of the transitions, the number of maps quickly increases. All these maps fight for entries in the megamorphic IC stub cache, eventually overwriting maps for other objects that are unrelated to o, which slows down the application overall. So +1 for moving to maps! |
Sorry, something went wrong.
|
btw, LGTM for getting this landed. :-) |
Sorry, something went wrong.
|
I think @fhinkel’s comment should still be addressed? |
Sorry, something went wrong.
|
Thanks for catching that @fhinkel, that changes everything! Updates pushed, pls review folks. v6 es/map-bench.js thousands=100 method="object": 0.26339184977485885 es/map-bench.js thousands=100 method="nullProtoObject": 0.23501547831916525 es/map-bench.js thousands=100 method="fakeMap": 0.212913507413461 es/map-bench.js thousands=100 method="map": 0.7449254838002358 master es/map-bench.js thousands=100 method="object": 0.35728933045594424 es/map-bench.js thousands=100 method="nullProtoObject": 0.029615543283847124 es/map-bench.js thousands=100 method="fakeMap": 0.028427891784159526 es/map-bench.js thousands=100 method="map": 0.15582199860352638 |
Sorry, something went wrong.
|
LGTM. Should we update the first comment with the new times and also point out, that it's ops/sec rather than seconds (so higher is faster). |
Sorry, something went wrong.
|
Good idea, done! @fhinkel is there a known speed regression for maps in later V8? We're comparing 5.1 to 5.4 here and that's a big slowdown, or could the test not be getting at the real numbers? |
Sorry, something went wrong.
|
I wonder if something else was going on during the benchmarking, because nullProtoObject and fakeMap also have a 10x slowdown. Let me try on my machine ... |
Sorry, something went wrong.
|
yea, I think you're right, new run on master: es/map-bench.js thousands=100 method="object": 0.10768888702936505 es/map-bench.js thousands=100 method="nullProtoObject": 0.11350308225508328 es/map-bench.js thousands=100 method="fakeMap": 0.12039689515526422 es/map-bench.js thousands=100 method="map": 0.38445207528844944 |
Sorry, something went wrong.
|
Too much variability between runs, bumping it back up to the millions and it stabilises a bit more: v6 es/map-bench.js millions=1 method="object": 0.18984850416666324 es/map-bench.js millions=1 method="nullProtoObject": 0.16044478686078825 es/map-bench.js millions=1 method="fakeMap": 0.1311882248350222 es/map-bench.js millions=1 method="map": 0.3121014937928409 master es/map-bench.js millions=1 method="object": 0.2220851555085364 es/map-bench.js millions=1 method="nullProtoObject": 0.19131381289232038 es/map-bench.js millions=1 method="fakeMap": 0.17931948397493905 es/map-bench.js millions=1 method="map": 0.28127750318241235 |
Sorry, something went wrong.
|
I think we can blame the variation on timing issues. I don't get a regression going from v6.0.0 to master. Node v6.0.0: ~/node/benchmark/es$ node --version v6.0.0 ~/node/benchmark/es$ node -e "console.log(process.versions.v8)" 5.0.71.35 ~/node/benchmark/es$ node map-bench.js es/map-bench.js millions=1 method="object": 0.3697918357000556 es/map-bench.js millions=1 method="nullProtoObject": 0.41595417356334285 es/map-bench.js millions=1 method="fakeMap": 0.36001723720769746 es/map-bench.js millions=1 method="map": 0.5557669893876821 Node v6.7.0: ~/node/benchmark/es$ node -e "console.log(process.versions.v8)" 5.1.281.83 ~/node/benchmark/es$ node map-bench.js es/map-bench.js millions=1 method="object": 0.4192028932525165 es/map-bench.js millions=1 method="nullProtoObject": 0.43625871109888 es/map-bench.js millions=1 method="fakeMap": 0.3631661863732719 es/map-bench.js millions=1 method="map": 0.5750817453541195 Node master: ~/node/benchmark/es$ ~/node/node -e "console.log(process.versions.v8)" 5.5.0 (candidate) ~/node/benchmark/es$ ~/node/node map-bench.js es/map-bench.js millions=1 method="object": 0.43575744375713865 es/map-bench.js millions=1 method="nullProtoObject": 0.4588149868110948 es/map-bench.js millions=1 method="fakeMap": 0.4051635672142672 es/map-bench.js millions=1 method="map": 0.6342556913214041 |
Sorry, something went wrong.
PR-URL: #7581 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <ranziska.hinkelmann@gmail.com>
PR-URL: #7581 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <ranziska.hinkelmann@gmail.com>
PR-URL: #7581 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <ranziska.hinkelmann@gmail.com>
PR-URL: #7581 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <ranziska.hinkelmann@gmail.com>
| Back | FazBrowse Home | New Git URL |
Given the discussion in #6102 about Map still being too slow to use I figured I'd see with a benchmark. @mscdex, @jasnell please review and let me know if you think this is valid.
As for why the fakeMap test is faster ... I got nothing ...
Update after @fhinkel noticed a serious flaw:
v6
master
Times are ops/sec, so higher is better