-
Notifications
You must be signed in to change notification settings - Fork 68
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
Performance improvements by providing caching for Configuration objects built from JSON configuration files #950
Conversation
b94cfea
to
6ff6b30
Compare
6ff6b30
to
c391259
Compare
I was curious why the keyMatches() function of the Comment and StripMergePrefix transformers showed in the profile but the keyMatches() calls from the other transformers did not. The two functions both use two different ways of checking the first character of the string for a specific character: return ( 0 === strpos($key, self::COMMENT_PREFIX) ); and return substr($key, 0, 1) === self::MERGE_PREFIX; Certainly the strpos() call is not ideal since it will have to scan the whole string if it does not contain a comment character (i.e most of the time). In my tests the following was about twice as fast: return $key[0] === self::COMMENT_PREFIX; |
I also wonder if there is any benefit of changing the recursivelySubstututeVariables() function to only call variablestore->substitute() if the string could contain a variable. Something like: if ( is_string($value) ) {
if (strpos($value, '${') !== null) {
$value = $this->variableStore->substitute($value);
}
} ... |
The original idea for comments was any key starting with a comment as the first non-whitespace character, but it turns out that we don't use it that way so it makes sense to change it to only compare the first character instead of using strpos(). |
I think that we can gain some performance improvement if we add the |
// object. We use serialize() instead of json_encode() because the latter only takes | ||
// into account public member variables and we have more complex objects that can be | ||
// passed as options such as VariableStore. | ||
$cacheKey = md5($filename . '|' . get_called_class() . '|' . serialize($options)); |
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.
If we ever have a hash collision then it will be a pain in the neck to try to debug the problem!
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.
True. Although I can generate the key leaving the filename and class as plain text and calculating the md5 only on the serialized object.
@jpwhite4 For whatever reason Xdebug or cachegrind appears to be grouping some of the calls to keyMatches() together. The sum seems reasonable but there are 4 classes utilized not 2 as reported. |
@jpwhite4 Significant relative performance improvements gained using |
597ef1b
to
c39d034
Compare
@jpwhite4 Can you re-approve this PR? I found and fixed a bug and made another performance improvement. |
Description
The
Configuration
and extending classes such asEtlConfiguration
andXdmodConfiguration
are now used to process all XDMoD configuration files and local overrides (e.g.,roles.json
and files inroles.d
) as well as ETL configuration files. The extremely flexible nature of these files introduces significant overhead when the same configuration file is required in multiple locations throughout the code to perform a given operation.This implements an object cache so that the same global configuration file (e.g.,
roles.d
) and local configuration files (e.g., files inroles.d
) only need to be parsed once with the resulting object stored in an object cache. Subsequent accesses are retrieved from the cache. The unique cache key is generated using the following pieces of information:get_called_class()
so we can distinguish betweenConfiguration
,EtlConfiguration
, etc.Configuration
or child classes. Options such as substitution variables will affect the generated object.The result is a significant reduction in the amount of times that
Configuration
related methods are called.Current Profile (8.5.0)
Usage Explorer get_data request:
/controllers/user_interface.php?&operation=get_data
Longest Calls:
Function list:
Simulate a click on a Usage Tab tree node to view summary charts:
/controllers/user_interface.php?&operation=get_data?&operation=get_charts
Longest Calls (no cycle detection):
Function list:
Profile with Config Object Cache
Note significant reduction in calls to
Configuration
related code. For example, calls toConfiguration->processKeyTransformers()
are reduced from 10,865 to 300 for Usage Tab summary charts.Usage Explorer get_data request:
/controllers/user_interface.php?&operation=get_data
Longest Calls:
Function list:
Simulate a click on a Usage Tab tree node to view summary charts:
/controllers/user_interface.php?&operation=get_data?&operation=get_charts
Longest Calls (no cycle detection):
Function list:
Motivation and Context
Performance improvements.
Tests performed
Ran tests locally and via shippable.
Types of changes
Checklist: