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
Improve include time of Mojo::Base by extracting monkey_patch #2173
base: main
Are you sure you want to change the base?
Conversation
c408463
to
949dbaa
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This should not be done. This creates a method in all classes using Mojo::Base as a base. |
Additionally, if Mojo::Util re-exports class_to_path no other adjustment should be necessary. |
This comment was marked as resolved.
This comment was marked as resolved.
done, updated |
BaseUtil seems reasonable and self-explanatory to me, but there may be other opinions. As long as Mojo::Util imports and re-exports the functions from there correctly, there should be no changes needed to other modules. |
Sure, let's see how that looks. Added a commit to combine monkey_patch and class_to_path in Mojo::BaseUtil and reverted changes in other modules to use still the functions as exported from Mojo::Util. |
IMO, t/mojo/util.t should remain unchanged, to ensure there is no change in compatibility for the re-exported functions. t/mojo/base_util.t may be unnecessary if so. |
I'd be interested in some real world benchmarks where this makes a difference. |
I'm looking forwards to seeing this hopefully soon in the library :) |
By simply copying over BEFORE: NOW: When running on my phone's termux, the change of those values is really felt. I compared before and after also with Nut Prof: BEFORE: AFTER: |
1942558
to
a8ba9a5
Compare
This comment was marked as outdated.
This comment was marked as outdated.
a8ba9a5
to
b7002c7
Compare
This comment was marked as outdated.
This comment was marked as outdated.
Please squash commits. |
b7002c7
to
597c50b
Compare
done |
597c50b
to
b200779
Compare
Covered all last three open review comments |
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.
Looks good to me
use Pod::Usage qw(pod2usage); | ||
use Socket qw(inet_pton AF_INET6 AF_INET); | ||
use Sub::Util qw(set_subname); |
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.
Do you think anyone depends on Mojo::Util::set_subname? They probably shouldn't but they could
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.
It isn't documented and the fix is trivial so I don't think I care at all.
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.
I would not consider use of any subroutines imported without a documented interface as our responsibility.
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.
No documentation, no feature.
|
||
subtest 'monkey_patch' => sub { | ||
{ | ||
|
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.
nitpick but blank line?
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.
ok, done. Included is a second commit removing redundant blank lines in the added code as well as where I originally copied the test code from.
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.
Nope, perltidy actually demands the blank line :D Reverted the last change
I think the name Mojo::BaseUtil is a bit awkward. How to tell what is in which package? I can't come up with a killer name, but I'm thinking about Mojo::CoreUtil or Mojo::PureUtil, which might indicate that the functions in that package is without any significant dependencies? I guess Mojo::BaseUtil makes sense, if we only have functions that Mojo::Base depends on, but I wonder if it's a slippery slope... Should any of the following functions be moved over? The reason I ask, is because maybe it makes sense to move class_to_file(), when class_to_path() was moved.
|
While that might make sense for code level consistency, I think it's beneficial to keep the module limited in scope to its stated purpose. All of these functions should continue to be used from Mojo::Util in normal cases. It can be viewed less as "moving" the functions from the user's POV because they continue to be re-exported. |
Then I think that should be stated in the documentation, meaning that functions can be added and removed in the future to keep Mojo::Base quick to load. |
It could make sense to me to remove the function documentation from the new module (these would need to be added as trusted in t/pod_coverage.t), and document that it provides functions for use in Mojo::Base and shouldn't be depended on to remain compatible. |
ok, fine for me. As there was already one "+1" I followed that suggestion and included that change Also included is a second commit removing redundant blank lines in the added code as well as where I originally copied the test code from. |
For my own cli script, I ended up doing this to avoid loading in thousands of subs right away: sub monkey_patch {
my ( $class, %patch ) = @_;
require Sub::Util;
for ( keys %patch ) {
*{"${class}::$_"} =
Sub::Util::set_subname( "${class}::$_", $patch{$_} );
}
} |
Commit 7e9a2ad introduced a "require Mojo::Util" causing a significant chain of further dependencies being pulled in which IMHO should be avoided for the very base module which is in particular being advertised as useful for just enabling strictures and common import checks. This commit moves out the function "monkey_patch" into its own module to break or prevent the circular dependency between Mojo::Base and Mojo::Util. With that the import of Mojo::Base is more efficient, `time perl -e 'use Mojo::Base` on my system reduced from 224±12.08 ms to 52.0±2.3 ms which I consider a considerable improvement for Mojo::Base which is used as a baseclass in many cases. Further minor changes included: * Directly require MonkeyPatch for cleaner subclassing + POD * Correct use of MonkeyPatch with empty import * Combine monkey_patch and class_to_path in new Mojo::BaseUtil
3fa30df
to
ef789ba
Compare
|
||
our @EXPORT_OK = (qw(class_to_path monkey_patch)); | ||
|
||
|
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.
Nitpick: Extra newline.
L<Mojo::BaseUtil> provides a C<class_to_path> and the C<monkey_patch> function | ||
for L<Mojo>. The main purpose is to provide functions to both C<Mojo::Base> | ||
and C<Mojo::Util> so that C<Mojo::Base> does not have to load the rest of | ||
C<Mojo::Util>. |
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.
Nitpick: Not 120 char lines.
use Mojo::BaseUtil qw(class_to_path monkey_patch); | ||
|
||
|
||
subtest 'class_to_path' => sub { |
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.
Nitpick: Extra newline.
@@ -11,4 +11,7 @@ my @await = ( | |||
qw(AWAIT_NEW_FAIL AWAIT_ON_CANCEL AWAIT_ON_READY AWAIT_WAIT) | |||
); | |||
|
|||
all_pod_coverage_ok({also_private => ['BUILD_DYNAMIC', @await, 'spurt']}); | |||
# base utils only to be used in Mojo::Base and should not be used elsewhere |
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.
Nitpick: Comment capitalisation.
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.
Is that correct english? Sounds a little wrong to me.
Motivation
Commit 7e9a2ad introduced a "require Mojo::Util" causing a significant chain of further dependencies being pulled in which IMHO should be avoided for the very base module which is in particular being advertised as useful for just enabling strictures and common import checks.
Summary
This commit moves out the function "monkey_patch" into its own module to break or prevent the circular dependency between Mojo::Base and Mojo::Util.
With that the import of Mojo::Base is more efficient,
time perl -e 'use Mojo::Base
on my system reduced from 224±12.08 ms to 52.0±2.3 ms which I consider a considerable improvement for Mojo::Base which is used as a baseclass in many cases.