-
Notifications
You must be signed in to change notification settings - Fork 7
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
make slowEqual not slow #128
Comments
This reverts commit 873940d.
Based on the benchmarks in #146, the suggested change here doesn't appear to improve |
I don't trust |
If someone's passing user input as |
I disagree. I think this code is safe because they can't do insert a comment then real code after it, in the style of SQL injection. should add a check that every item in target is a string, |
@dominictarr It would only take a Also - if you follow the CVE link, you may find one of the mentioned pages specifically mentions the |
to make that bug actually work, the stringify needs to be running with a reviver function. which this one isn't. or, I think if you passed it an object with a custom toValue method, but that can't be done remotely (only in the local js vm) to attack this you'd need to get JSON.stringify to actually output the wrong thing. |
but yes, this doesn't matter unless it's actually faster or not... I was confused about the PR, it seemed to say that the benchmarks didn't use createSeekPath? the docs say that slowEqual is slow... but is there a benchmark that shows that? maybe slow equal isn't slow? or there are other things that make the impact of slow equal insignificant, but when I was developing this stuff I recall this stuff had significant impact |
@dominictarr I setup two pull requests in my fork to trigger the benchmark, and |
is one of those results the hand written query? is it "Query 1 big index"? how big is the log? are there records that match and also do not match? btw, why are you putting it inside the if that might return undefined? it returns -1 to mean not found because this can be checked with a single operator, and doesn't change return types. When you have a polymorphic function it isn't as optimizable, so better to avoid this. Also, createSeekPath tries to avoid using closures then you added one back ;) now, js perf can be very finnicky and the engine optimizations might have changed since I wrote that, you have to actually measure this... so I could be wrong... but in bipf/test/perf the difference between seekPath and createSeekPath does make a difference |
@dominictarr Looks like the difference is that the JITDB benchmark factors the compilation time into the benchmark & JITDB wasn't caching the compiled code. If we update JITDB to cache/memoize |
@dominictarr I introduced a static module-level LRU cache optimization to LRU cache
LRU cache with
|
Part | Speed | Heap Change | Samples |
---|---|---|---|
Query 1 big index with slowEqual (1st run) | 915.94ms ± 6.73ms | 8.63 kB ± 0 kB | 59 |
Query 1 big index with slowEqual (2nd run) | 319.64ms ± 3.36ms | 68.74 kB ± 38.55 kB | 42 |
Query 1 big index with slowEqual (3rd run) | 0.5ms ± 0.18ms | 10.55 kB ± 24.38 kB | 44 |
It looks like bipf.createSeekPath
makes the first query faster, but not later queries. Note though that these numbers completely exclude the compilation time, which would be a serious consideration for very dynamic paths in the queries.
I just noticed that the original and LRU cache with pregenerated comparison buffer
@arj03 @staltz What are your thoughts on this solution? |
@Barbarrosa great job! |
which benchmark is equals? is slowEquals as fast as that now? |
@dominictarr
|
Thinking back, |
I think two more benchmarks may be worth looking at here. Original
|
Part | Speed | Heap Change | Samples |
---|---|---|---|
Query 1 big index with slowEqual (1st run) | 1227.72ms ± 30.83ms | -43.01 kB ± 18.86 kB | 45 |
Query 1 big index with slowEqual (2nd run) | 302.25ms ± 1.66ms | 77.83 kB ± 0 kB | 40 |
Query 1 big index with slowEqual (3rd run) | 0.29ms ± 0.02ms | 21.15 kB ± 0 kB | 44 |
Pregenerated buffer w/o LRU cache
Part | Speed | Heap Change | Samples |
---|---|---|---|
Query 1 big index with slowEqual (1st run) | 1253.71ms ± 24.5ms | 32.54 kB ± 45.04 kB | 43 |
Query 1 big index with slowEqual (2nd run) | 307.64ms ± 2.64ms | -15.19 kB ± 12.49 kB | 43 |
Query 1 big index with slowEqual (3rd run) | 0.62ms ± 0.32ms | 7.5 kB ± 43.83 kB | 42 |
I was curious about the impact if the LRU cache was set per JITDB instance. Here's that result. Per-instance LRU cache w/ pregenerated buffer
|
@dominictarr It's querying for msgs of type post, there are 23310 of those and the log in total has 100000 msgs and 2000 feeds. This log is deterministically generated with ssb-fixtures which uses statistical sampling based on real-world SSB statistics and the Pareto distribution. |
perfect! |
@dominictarr #154 (now merged) implements something similar to the change I suggested, i.e. it preprocesses the queried path into an array of |
there is a method in bipf to generate the createSeekPath method
https://github.com/ssbc/bipf/blob/master/index.js#L299-L317
it generates source code and creates a new function because it can generate flatter, faster, code without closure scoping.
then you won't need the indexType option, because you can just use the path.
The text was updated successfully, but these errors were encountered: