-
Notifications
You must be signed in to change notification settings - Fork 39
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 performance of WinProcess.getEnvironmentVariables() #69
Conversation
test code was only checking that the returned environment variable map ontained the "TEST" environment variable, however if the code returned incorrectly then the test would still pass. This adds a unit test to ensure future changes do not regress behaviour
@@ -159,36 +157,23 @@ private void parseCmdLineAndEnvVars() { | |||
String s = Native.getCmdLineAndEnvVars(pid); | |||
if(s==null) | |||
throw new WinpException("Failed to obtain for PID="+pid); | |||
int sep = s.indexOf('\0'); | |||
commandline = s.substring(0,sep); | |||
envVars = new TreeMap<String,String>(CASE_INSENSITIVE_COMPARATOR); |
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.
the old CASE_INSENSITIVE_COMPARATOR
was inefficient - running String.toUpperCase
repeatedly on insertion.
} else { | ||
t = s.substring(0,sep); | ||
s = s.substring(sep+1); |
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.
the other part of the inefficiency was just chopping the string down, and creating substrings from it. Far more efficient to scan the entire String once and chop it.
if (end != -1) { | ||
s = s.substring(0, end); | ||
} | ||
StringTokenizer st = new StringTokenizer(s, "\0", false); |
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.
despite the fact that javadoc points you to use String.split(string regexp)
it is no where near as performant according to the benchmark.
} | ||
StringTokenizer st = new StringTokenizer(s, "\0", false); | ||
commandline = st.nextToken(); | ||
envVars = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER); |
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.
using String.CASE_INSENSITIVE_ORDER
which can shortcut the comparison as it uses String.compareIgnoreCase()
which can in the optimim just look at the first character, so avoids an entire upper-casing of each string on comparison.
static { | ||
ARCHITECTURE_DEPENDANT_ENVIRONMENT_VARS = new HashSet<>(); | ||
ARCHITECTURE_DEPENDANT_ENVIRONMENT_VARS.add("PROCESSOR_ARCHITEW6432"); | ||
ARCHITECTURE_DEPENDANT_ENVIRONMENT_VARS.add("PROCESSOR_ARCHITECTURE"); | ||
ARCHITECTURE_DEPENDANT_ENVIRONMENT_VARS.add("PROGRAMFILES"); | ||
ARCHITECTURE_DEPENDANT_ENVIRONMENT_VARS.add("COMMONPROGRAMFILES"); | ||
} |
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.
there may be more - these where what I observed on my windows 11 x64 environment.
Map<String, String> processEnv = wp.getEnvironmentVariables(); | ||
|
||
// environment variable that start with = is just some funky stuff! | ||
// and there are some that start with "=" that won't show up in set e.g. =ExitCode =CLINK.SCRIPTS |
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 could not find any documentation on this (starting with =
, but they exist and are funky!
so just excluded them from the test
e.g.
set
echo %=ExitCode%
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, bumping to Java 1.8 is perfectly fine at this moment.
Note that I do not longer have release environment for Windows components and Maven Central. Please contact @batmat and @MarkEWaite to discuss who will take care of thios component, and I will help with getting permissions. Bonus points for a Jenkins devlist thread
Are you the only maintainer currently @oleg-nenashev? As the module appears to be used outside of Jenkins (still in my Idea distrubution) is the Jenkins dev-list the best place for this to happen, as the Jenkins needs may well be different from others. |
https://groups.google.com/g/jenkinsci-dev/c/JmdP7Z0_ppc Also cc @segrey |
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.
Thanks for the PR!
Thanks for merging Basil, I had forgotten about this one. |
fixes #68 / JENKINS-67681
The performance of the code was no longer efficient in a Java5 world where
String.substring
involves memory copying to prevent holding onto larger strings preventing GC.Benchmark showed the following:
the java code used to take approximately .9ms per call and now takes approx 0.01ms