Skip to content

[Sqlparser] Pool the yyParserImpls#4175

Merged
sougou merged 1 commit intovitessio:masterfrom
danieltahara:parser-pool
Sep 5, 2018
Merged

[Sqlparser] Pool the yyParserImpls#4175
sougou merged 1 commit intovitessio:masterfrom
danieltahara:parser-pool

Conversation

@danieltahara
Copy link

@danieltahara danieltahara commented Sep 3, 2018

For a high QPS application, the sqlparser generates a ton of garbage.

622GB    26.33% 60.87%   880.50GB 37.28% vitess.io/vitess/go/vt/sqlparser.yyParse
212.57GB  9.00% 69.87%   258.49GB 10.94% vitess.io/vitess/go/vt/sqlparser.(*yyParserImpl).Parse

Most of this, per the heap profile is allocations of new yyParserImpl
objects for every call to yyParse. This diff uses sync.Pool to
mitigate the total allocation overhead. Results:

benchmark                     old ns/op     new ns/op     delta
BenchmarkNormalize-4          2540          2641          +3.98%
BenchmarkParse1-4             18269         13923         -23.79%
BenchmarkParse2-4             46703         41721         -10.67%
BenchmarkParse2Parallel-4     22246         20290         -8.79%
BenchmarkParse3-4             4064743       4151772       +2.14%

benchmark                     old allocs     new allocs     delta
BenchmarkNormalize-4          27             27             +0.00%
BenchmarkParse1-4             75             74             -1.33%
BenchmarkParse2-4             264            263            -0.38%
BenchmarkParse2Parallel-4     176            175            -0.57%
BenchmarkParse3-4             360            361            +0.28%

benchmark                     old bytes     new bytes     delta
BenchmarkNormalize-4          821           821           +0.00%
BenchmarkParse1-4             22776         2304          -89.88%
BenchmarkParse2-4             28352         7875          -72.22%
BenchmarkParse2Parallel-4     25712         5234          -79.64%
BenchmarkParse3-4             6352082       6336288       -0.25%

Resolves: #4174

Signed-off-by: Daniel Tahara tahara@dropbox.com

@danieltahara
Copy link
Author

danieltahara commented Sep 3, 2018

EDIT: Fixed. Need to reinitialize yyParserImpl.lval

Getting some error on ParseNext, but only for one of the tests

➜  sqlparser git:(parser-pool) ✗ go test
--- FAIL: TestIgnoreSpecialComments (0.00s)
        parse_next_test.go:77: got select 1 from dual want select 2 from dual

@danieltahara danieltahara force-pushed the parser-pool branch 2 times, most recently from 68cf244 to 5589faa Compare September 3, 2018 23:56
@sougou
Copy link
Contributor

sougou commented Sep 4, 2018

I'm actually surprised you're getting any benefit. For large size allocations like in this case, the cost of zeroing the memory is significant. This is something you're doing in a loop whereas the runtime can do it as a sweep.

The variance is probably related to just the cost of obtaining the memory, which will vary depending on fragmentation level. Are you able to get consistent numbers?

One experiment you can try (instead of the loop) is to have a static zero-initialized yyParserImpl, and just assign that to the one you got from the pool, which is likely to zero it out more efficiently.

@danieltahara
Copy link
Author

That's a good idea.

In any event, there are some issues with holding references to the "backing" stack. I need to sort those out before going forward

@danieltahara
Copy link
Author

And to answer your other question, the numbers are consistent from run to run.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsurprisingly, this turns out to be a problem:

panic: interface conversion: interface is nil, not sqlparser.SQLNode [recovered]
        panic: interface conversion: interface is nil, not sqlparser.SQLNode

goroutine 77 [running]:
testing.tRunner.func1(0xc4206823c0)
        /usr/local/go/src/testing/testing.go:742 +0x29d
panic(0x662e60, 0xc42070c180)
        /usr/local/go/src/runtime/panic.go:502 +0x229
vitess.io/vitess/go/vt/sqlparser.(*TrackedBuffer).Myprintf(0xc420164900, 0x6b7bd9, 0x9, 0xc42005dd08, 0x1, 0x1)
        /home/tahara/vitess/src/vitess.io/vitess/go/vt/sqlparser/tracked_buffer.go:97 +0x3ba
vitess.io/vitess/go/vt/sqlparser.(*Show).Format(0xc4200824b0, 0xc420164900)
        /home/tahara/vitess/src/vitess.io/vitess/go/vt/sqlparser/ast.go:1498 +0x1a3
vitess.io/vitess/go/vt/sqlparser.(*TrackedBuffer).Myprintf(0xc420164900, 0x6b60ed, 0x2, 0xc42005de70, 0x1, 0x1)
        /home/tahara/vitess/src/vitess.io/vitess/go/vt/sqlparser/tracked_buffer.go:99 +0x3ff
vitess.io/vitess/go/vt/sqlparser.String(0x7fd7c9a1ee68, 0xc4200824b0, 0xc4200824b0, 0x7fd7c9a1ee68)
        /home/tahara/vitess/src/vitess.io/vitess/go/vt/sqlparser/ast.go:249 +0xe4
vitess.io/vitess/go/vt/sqlparser.TestValid(0xc4206823c0)
        /home/tahara/vitess/src/vitess.io/vitess/go/vt/sqlparser/parse_test.go:1347 +0x20a
testing.tRunner(0xc4206823c0, 0x6d2920)
        /usr/local/go/src/testing/testing.go:777 +0xd0
created by testing.(*T).Run
        /usr/local/go/src/testing/testing.go:824 +0x2e0
exit status 2
FAIL    vitess.io/vitess/go/vt/sqlparser        0.040s

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. there was a dangling reference from ShowCollationFilterOpt, which is resolved in this diff

@danieltahara danieltahara force-pushed the parser-pool branch 2 times, most recently from 34d61fa to 2cc1e1d Compare September 4, 2018 01:06
For a high QPS application, the sqlparser generates a ton of garbage.
```
622GB    26.33% 60.87%   880.50GB 37.28% vitess.io/vitess/go/vt/sqlparser.yyParse
212.57GB  9.00% 69.87%   258.49GB 10.94% vitess.io/vitess/go/vt/sqlparser.(*yyParserImpl).Parse
```

Most of this, per the heap profile is allocations of new `yyParserImpl`
objects for every call to `yyParse`. This diff uses `sync.Pool` to
mitigate the total allocation overhead.

Modifies sql.y to fix a place where we took a reference to a stack
variable rather than making an intermediate copy.

Resolves vitessio#4174

Signed-off-by: Daniel Tahara <tahara@dropbox.com>
@sougou sougou merged commit 28a97fc into vitessio:master Sep 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants