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
fix a caching problem in OO code causing a 4.11 performance regression #10096
Conversation
The regression was introduced by ocaml#9096 in this part of the diff: | Tcf_method (name, _, Tcfk_concrete (_, exp)) -> - let met_code = msubst true (transl_exp exp) in + let scopes = enter_method_definition ~scopes name.txt in + let met_code = + msubst true (transl_scoped_exp ~scopes exp) in transl_exp would use Translobj.oo_wrap on functions, while the new transl_scoped_expr does not. The regression was first reported by Sacha Ayoun in ocaml#10092, as it results in a large slowdown (2x slower) on the Gillian codebase, which uses an object-oriented visitor in a performance-critical way.
Here is a microbenchmark that reproduces the problem: let test n =
let obj = object
method add42 i = 42 + i
end in
obj#add42 n
let n_iters = int_of_string Sys.argv.(1)
let () =
for i = 1 to n_iters do
ignore (test i)
done On my machine,
In this microbenchmark, class initialization takes more time than actual usage of the object. I suppose that this corresponds to real-world use-cases where object-oriented visitors are created locally within traversal functions, but then used on very small inputs most of the time. |
I see another occurrence of |
This PR fixes The underlying problem was that |
The fix adds an |
Excellent, we now have two reviewers for this PR! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes the bug, but there is still a call to:
List.iter (Translattribute.check_attribute e) e.exp_attributes;
is transl_exp
that is being inadvertently left out by transl_scoped_exp
.
This pattern seems quite error prone. I think replacing transl_scoped_exp
by an additional boolean parameter on transl_exp
would be better. Perhaps renaming transl_exp
to transl_exp1
and then having transl_exp
and transl_scoped_exp
that call into it with the boolean parameter set to true
and false
respectively.
@lpw25 Thanks for the suggestion. I pushed a new commit in the direction that you suggest. This makes the code nicer, but the change is also more invasive, so I guess it should be reviewed carefully. |
0fd43cb
to
26d35b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I'd probably have left transl_bound_exp
as it was, but the patch is fine either way.
26d35b5
to
f06c8f1
Compare
There is an interesting question here, asked at an interesting time of the year: do we want to backport this fix to 4.11 and make a new minor release? Personally I think this would be a good idea, given that (4.11 is still the last release and) we are fixing a performance regression that can be very large (2x slowdown) for some users workflow existing in the wild. (cc @Octachron) |
I haven't checked, but I suspect LexiFi's codebase (which uses objects heavily but has not yet been ported to 4.11) would be impacted by this. Based on that, I would be in favour of backporting to 4.11, even if there is no minor release done. |
What I will do is to include this change in a "4.11 maintenance branch" section of the Changes, and backport in the 4.11 branch. We can decide having a bugfix release later on. |
(suggestion by Leo White)
f06c8f1
to
c987f3d
Compare
I agree that this seems worthwhile to backport this fix to both 4.12 and 4.11 . |
c987f3d
to
001d7db
Compare
fix a caching problem in OO code causing a 4.11 performance regression (cherry picked from commit 9f53c6b)
fix a caching problem in OO code causing a 4.11 performance regression (cherry picked from commit 9f53c6b)
The regression was introduced by #9096 in this part of the diff:
transl_exp
would useTranslobj.oo_wrap
on functions, while the newtransl_scoped_exp
does not.The regression was first reported by @giltho in #10092, as it
results in a large slowdown (2x slower) on the Gillian codebase, which
uses an object-oriented visitor in a performance-critical way.