-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Avoid generic array instantation in hot paths #5911
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
Conversation
} else { | ||
val result = new Array[asm.Type](numCapturedParams) | ||
result(0) = typeToBType(lambdaTarget.owner.info).toASMType | ||
capturedParams.iterator.map(sym => typeToBType(sym.info).toASMType).copyToArray(result, 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.
There is a bug here. This loses the last parameter. The array should be numCapturedParams+1
- copyToArray will simply throw away the arguments that do not fix.
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 numCapturedParams
ever 0? If so this could be optimised further.
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.
Good catch. Turns out the second branch (!isStatic
) is never taken, as we chose to make all lambda implementation methods static, which meant we could leave them public without having to mangle the names. But I've pushed a fix in case this becomes live code in the future.
val (capturedParams, lambdaParams) = lambdaTarget.paramss.head.splitAt(lambdaTarget.paramss.head.length - arity) | ||
val invokedType = asm.Type.getMethodDescriptor(asmType(functionalInterface), (receiver ::: capturedParams).map(sym => typeToBType(sym.info).toASMType): _*) | ||
val numCapturedParams = lambdaTarget.paramss.head.length - arity | ||
val (capturedParams, lambdaParams) = lambdaTarget.paramss.head.splitAt(numCapturedParams) |
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 is a special case where arity == 0 which avoid the splitAt
List.splitAt could be optimized where split == 0 and in for Nil - seperate PR probably
@@ -501,7 +501,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { | |||
currentRun.symData get sym match { | |||
case Some(pickle) if !nme.isModuleName(newTermName(jclassName)) => | |||
val scalaAnnot = { | |||
val sigBytes = ScalaSigBytes(pickle.bytes.take(pickle.writeIndex)) | |||
val sigBytes = ScalaSigBytes(java.util.Arrays.copyOf(pickle.bytes, pickle.writeIndex)) |
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.
why this change - isnt this what .take does as we fixed the Array methods
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.
Good point. We had to revert that change in #5821 because it wasn't binary compatible. We should re-apply the original patch to the 2.13.x branch.
I"m going to close this PR for now as the benchmark isn't conclusive. I re-ran it and got 1054ms vs 1056ms. |
Before:
After: