Skip to content

C++: Fix performance of leap year queries#1536

Merged
geoffw0 merged 2 commits intogithub:masterfrom
jbj:leap-year-sameBaseType-perf
Jul 2, 2019
Merged

C++: Fix performance of leap year queries#1536
geoffw0 merged 2 commits intogithub:masterfrom
jbj:leap-year-sameBaseType-perf

Conversation

@jbj
Copy link
Contributor

@jbj jbj commented Jul 2, 2019

The sameBaseType predicate was fundamentally quadratic, and this blew up on large C++ code bases. Replacing it with calls to Type.stripType fixes performance and does not affect the qltests. It looks like sameBaseType was used purely an ad hoc heuristic, so I'm not worried about the slight semantic difference between sameBaseType and stripType.

The `sameBaseType` predicate was fundamentally quadratic, and this blew
up on large C++ code bases. Replacing it with calls to `Type.stripType`
fixes performance and does not affect the qltests. It looks like
`sameBaseType` was used purely an ad hoc heuristic, so I'm not worried
about the slight semantic difference between `sameBaseType` and
`stripType`.
@jbj jbj added the C++ label Jul 2, 2019
@jbj jbj requested a review from a team as a code owner July 2, 2019 09:24
@jbj
Copy link
Contributor Author

jbj commented Jul 2, 2019

This PR reduces the time to evaluate StructWithExactEraDate.ql on uoip/g2opy from 6100s to no time at all.

@jbj
Copy link
Contributor Author

jbj commented Jul 2, 2019

Hang on, there's another performance problem: the setter and getter predicates are very slow on CoreCLR. I'll see if I can fix it and extend this PR.

The predicates `getter` and `setter` in `StructLikeClass.qll` were very
slow on some snapshots. On https://github.com/dotnet/coreclr they had
this performance:

    StructLikeClass::getter#fff#antijoin_rhs ........... 3m55s
    Variable::Variable::getAnAssignedValue_dispred#bb .. 3m36s
    StructLikeClass::setter#fff#antijoin_rhs ........... 20.5s

The `getAnAssignedValue_dispred` predicate in the middle was slow due to
magic propagated from `setter`.

With this commit, performance is instead:

   StructLikeClass::getter#fff#antijoin_rhs ........... 497ms
   Variable::Variable::getAnAssignedValue_dispred#ff .. 617ms
   StructLikeClass::setter#fff#antijoin_rhs ........... 158ms

Instead of hand-optimizing the QL for performance, I simplified `setter`
and `getter` to require slightly stronger conditions. Previously, a
function was only considered a setter if it had no writes to other
fields on the same class. That requirement is now relaxed by dropping
the "on the same class" part. I made the corresponding change for what
defines a getter. I think that still captures the spirit of what getters
and setters are.

I also changed the double-negation with `exists` into a `forall`.
@jbj
Copy link
Contributor Author

jbj commented Jul 2, 2019

I've added a commit to fix the CoreCLR performance problem.

Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

The code change looks sensible.

I don't see any speedup on the majority of projects I tested on, and when I did (Qt), it wasn't as drastic as what you describe:

	StructWithExactEraDate.ql-4:StructLikeClass::setter#ffb#antijoin_rhs ................... 26.2s
	StructWithExactEraDate.ql-4:StructLikeClass::sameBaseType#ff ........................... 21.7s
	StructWithExactEraDate.ql-3:Enclosing::exprEnclosingElement#ff ......................... 7.6s (executed 96 times)

(total 114s)
->

	StructWithExactEraDate.ql-4:StructLikeClass::setter#ffb#antijoin_rhs ................... 23.4s
	StructWithExactEraDate.ql-3:Enclosing::exprEnclosingElement#ff ......................... 7.8s (executed 96 times)

(total 86s)

I'm happy to merge this, but I'm not confident it solves the problem entirely.

@geoffw0
Copy link
Contributor

geoffw0 commented Jul 2, 2019

I'm now working on a performance fix for getter and setter. Are you happy for me to merge this PR now, or do you want to investigate further first?

Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

Noticed that you pushed a fix for that. Your fix LGTM, merging...

@geoffw0
Copy link
Contributor

geoffw0 commented Jul 2, 2019

redo failed

@geoffw0 geoffw0 merged commit e079406 into github:master Jul 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments