C++: Fix performance of leap year queries#1536
Conversation
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`.
|
This PR reduces the time to evaluate |
|
Hang on, there's another performance problem: the |
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`.
|
I've added a commit to fix the CoreCLR performance problem. |
geoffw0
left a comment
There was a problem hiding this comment.
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.
|
I'm now working on a performance fix for |
geoffw0
left a comment
There was a problem hiding this comment.
Noticed that you pushed a fix for that. Your fix LGTM, merging...
|
redo failed |
The
sameBaseTypepredicate was fundamentally quadratic, and this blew up on large C++ code bases. Replacing it with calls toType.stripTypefixes performance and does not affect the qltests. It looks likesameBaseTypewas used purely an ad hoc heuristic, so I'm not worried about the slight semantic difference betweensameBaseTypeandstripType.