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
LDEV-2127 use stringbuilder for bytecode (v2) #2315
base: 6.1
Are you sure you want to change the base?
LDEV-2127 use stringbuilder for bytecode (v2) #2315
Conversation
refiled from lucee#1758 as rebase got ugly) https://luceeserver.atlassian.net/browse/LDEV-2127 code review comments still pending
// only creates the stringbuilder object once | ||
adapter.newInstance(Types.STRING_BUILDER); | ||
adapter.dup(); | ||
adapter.invokeConstructor(Types.STRING_BUILDER, CONSTR_NO_STRING); // TODO pass left into constructor |
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.
instead of calling append twice, call the constructor with a string, so instead of
new StringBuilder().append(left).append(right).toString();
you do
new StringBuilder(left).append(right).toString();
OR maybe the following is faster?
new StringBuilder(left.length()+right.length()).append(left).append(right).toString();
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 still think that StringBuilder comes with unnecessary overhead
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.
thinking about it, i think we can break down what StringBuilder makes and create a method that does the same but much more optimized
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.
created some test code
public static void main(String[] args) {
int max = 1000000;
double tmp, start, res1 = Double.MAX_VALUE, res2 = Double.MAX_VALUE, res3 = Double.MAX_VALUE, res4 = Double.MAX_VALUE;
String left = "John Maynard war unser Steuermann, Aushielt er, bis er das Ufer gewann, ";
String right = "Er hat uns gerettet, er trägt die Kron, Er starb für uns, unsre Liebe sein Lohn.";
for (int y = 0; y < 100; y++) {
// ()
start = SystemUtil.millis();
for (int i = 0; i < max; i++) {
new StringBuilder().append(left).append(right).toString();
}
tmp = SystemUtil.millis() - start;
if (tmp < res1) res1 = tmp;
// (String)
start = SystemUtil.millis();
for (int i = 0; i < max; i++) {
new StringBuilder(left).append(right).toString();
}
tmp = SystemUtil.millis() - start;
if (tmp < res2) res2 = tmp;
// (int)
start = SystemUtil.millis();
for (int i = 0; i < max; i++) {
new StringBuilder(left.length() + right.length()).append(left).append(right).toString();
}
tmp = SystemUtil.millis() - start;
if (tmp < res3) res3 = tmp;
// concat
start = SystemUtil.millis();
for (int i = 0; i < max; i++) {
left.concat(right);
}
tmp = SystemUtil.millis() - start;
if (tmp < res4) res4 = tmp;
}
print.e("<init>(): " + res1);
print.e("<init>(String): " + res2);
print.e("<init>(int): " + res3);
print.e("concat: " + res4);
}
gives me the following result
<init>(): 13.766375005245209
<init>(String): 12.96975001692772
<init>(int): 11.805583000183105
concat: 17.216666996479034
so it is faster, but my open question ism how many instaces of StringBuilder will we have that the GC need to clean up, atm we win 6ms with 1'000'000 concats
refiled from #1758 as rebase got ugly)
https://luceeserver.atlassian.net/browse/LDEV-2127
code review comments still pending