Skip to content
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

Lots of allocations and time spent in LexFilter #6006

Closed
TIHan opened this issue Dec 13, 2018 · 9 comments
Closed

Lots of allocations and time spent in LexFilter #6006

TIHan opened this issue Dec 13, 2018 · 9 comments

Comments

@TIHan
Copy link
Contributor

TIHan commented Dec 13, 2018

The results are from when I did a trace with this PR: #6001

Now that source files are not showing up in the traces anymore, we can start to see what's coming up next in our list.

These traces were done when making a single modification in the middle of TypeChecker.fs, around line 6699 then waiting for semantic classification to kick in as well as errors.

GC Heap Allocs
untitled

Cpu Stacks
untitled2

--

The next traces below are the same thing, except I removed calls to Tokenizer.getClassifiedSpans in some of our analyzers.

GC Heap Allocs
untitled3

Cpu Stacks
untitled4

It seemed to make a slight bit of a difference, but LexFilter and interpret still show up at top in Cpu Stacks and TokenTup (it's inside LexFilter) in GC Heap Allocs.

My fear was that calls to Tokenizer.getClassifiedSpans were slowing things down due to brace completions and syntactic classification.

@TIHan TIHan changed the title Lots of allocations and time spent in LexFilter / Lexing Lots of allocations and time spent in LexFilter Dec 13, 2018
@gerardtoconnor
Copy link

Hi @TIHan , just to log our slack discussion, my proposed changes in lexfilter.fs to structures of TokenTup, LexbufState & PositionTuple yielded about 33% allocation improvement time, about 3% to overall time. It's not a final solution but does trim a third off the execution times of TokenTup. I changed LexbufState & PositionTuple to Class objects, and the TokenTup to a Struct as it was being splintered all over the place having to do heavy struct copies of the LexbufState & PositionTuple ( 20 ints and a bool copy in LexbufState & 10 int copies for PositionTuple.

Can I do a PR for this or do we need further investigation?

//[<Struct>]  << no longer Struct
type LexbufState(startPos: Position, 
                 endPos  : Position, 
                 pastEOF : bool) = 
    member x.StartPos = startPos
    member x.EndPos = endPos
    member x.PastEOF = pastEOF

//[<Struct>] << no longer Struct
type PositionTuple =
    val X: Position
    val Y: Position
    new (x: Position, y: Position) = { X = x; Y = y }

/// Used to save the state related to a token
//[<Class>] << no longer class
[<Struct>]
type TokenTup = 
    val Token : token
    val LexbufState : LexbufState
    val LastTokenPos: PositionTuple
    new (token,state,lastTokenPos) = { Token=token; LexbufState=state;LastTokenPos=lastTokenPos }

image

@forki
Copy link
Contributor

forki commented Dec 13, 2018

In any case a PR is a good thing - it would run full test suite and show if it's valid optimization

@gerardtoconnor
Copy link

👍 Ok, will do, I have few other ideas how to do small fringe improvements, I can include also if yielding further benefit in my crude benchmark. I'm not home till late but will try do at some stage today.

@cartermp
Copy link
Contributor

@gerardtoconnor Yes, please do submit a PR. We can tweak things from there but incremental improvements like this end up moving the needle meaningfully over time.

@cartermp cartermp added this to the 16.0 milestone Dec 13, 2018
@TIHan
Copy link
Contributor Author

TIHan commented Dec 13, 2018

A PR will be fine. We should evaluate what you changed and get evidence of better performance. Judging by what you recorded, it looks like it was an improvement.

@gerardtoconnor
Copy link

PR #6010 made to apply these changes … I ended up restructuring Position also so that the overhead is now only 2% vs our original 9% … but for some reason, other calls have come down too and reduced the base so technically improvement is better (or test case usage is now smaller somehow!!?). If @TIHan can validate the improvement would be great.

@chinwobble
Copy link

@TIHan Is it possible you could point to some documentation on how to generate and analyse these traces?

@cartermp
Copy link
Contributor

@chinwobble You can take a look here: https://blogs.msdn.microsoft.com/dotnet/2012/10/09/improving-your-apps-performance-with-perfview/

That will get you going. Once you get this sort of info, interpreting it does require some understanding of the codebase and what should show up as producing a lot of allocations/lots of CPU time or not.

@cartermp cartermp modified the milestones: 16.0, 16.1 Feb 21, 2019
@cartermp cartermp modified the milestones: 16.1, 16.2 Apr 23, 2019
@cartermp cartermp modified the milestones: 16.2, Backlog Apr 30, 2019
@TIHan
Copy link
Contributor Author

TIHan commented Oct 2, 2020

Closing as we solved the big issue with allocations of TokenTup a while back by implementing a pool.

@TIHan TIHan closed this as completed Oct 2, 2020
@cartermp cartermp modified the milestones: Backlog, 16.8 Oct 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants