Slide 1

Slide 1 text

COMPROMISING READABILITY

Slide 2

Slide 2 text

Performance

Slide 3

Slide 3 text

USING PPROF FLAME GRAPH

Slide 4

Slide 4 text

USING PPROF FLAME GRAPH

Slide 5

Slide 5 text

USING PPROF FLAME GRAPH

Slide 6

Slide 6 text

RUNTIME SIGNATURES TO LOOK FOR makeslice growslice someslice := make([]*thing, 1024) someslice = append(someslice, anotherslice) newobject something := &thing{…}

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

REDUCE THE NEED TO GROW A SLICE Old version, calls to append() may have to grow slice

Slide 9

Slide 9 text

REDUCE THE NEED TO GROW A SLICE New version, original allocation is sufficient, no need to grow.

Slide 10

Slide 10 text

REDUCING ALLOCATION BY INTRODUCING A BACKING SLICE Old version, allocs new object every time through the loop

Slide 11

Slide 11 text

REDUCING ALLOCATION BY INTRODUCING A BACKING SLICE New version, allocates all objects in single call to runtime

Slide 12

Slide 12 text

REUSE (EXTERNAL) Old version always returns new instance of PostingsList

Slide 13

Slide 13 text

REUSE (EXTERNAL) New version let's caller decide if/when/how to reuse a PostingsList

Slide 14

Slide 14 text

REUSE (INTERNAL) Old version always returns new instance of DictEntry

Slide 15

Slide 15 text

REUSE (INTERNAL) New version ALWAYS reuses the same DictEntry

Slide 16

Slide 16 text

REUSING INTERNAL VS EXTERNAL Internal External Pro Simpler API Caller has full control of reuse (or never use it at all by passing in nil) Con Lifcecycle of reuse is dictated by the component Clutters the API NOTE: in both cases the caller can misuse and get into trouble

Slide 17

Slide 17 text

REUSE OFTEN REQUIRES RESET struct slice *thing = Thing{} someslice = someslice[:0] All struct members go back to zero-value. Slice len set to 0, cap remains

Slide 18

Slide 18 text

RESET IN PRACTICE Hang on to slice reference, reset struct to zero values, reset slice, associate struct reference to reset slice.

Slide 19

Slide 19 text

REUSING VIA POOLS (MANUAL) ALLOCATE IN BLOCKS OF 256 AT A TIME RESET ITEM ON WAY OUT OF POOL

Slide 20

Slide 20 text

REUSING VIA SYNC.POOL NOTICE this is package level variable

Slide 21

Slide 21 text

REUSING VIA SYNC.POOL … do work reusing vcd (visit document context) get from pool return to pool PRO: reuse spans goroutines PRO: runtime reclaims items in the pool during GC CON: hard to use well in practice

Slide 22

Slide 22 text

NECESSARY COMPLEXITY ▸ Everything you've seen here is real from Couchbase's bleve/vellum projects ▸ As ugly as they are, they've all shown measurable improvements to important metrics @mschoch marty.schoch@gmail.com