-
Notifications
You must be signed in to change notification settings - Fork 41.3k
Use sized array for List.toArray() #12153
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
@@ -92,7 +92,7 @@ public void shouldCreateInstancesForReactiveAndImperativeRepositories() { | |||
CouchbaseReactiveRepositoriesAutoConfiguration.class }) { | |||
names.add(type.getName()); | |||
} | |||
return names.toArray(new String[0]); | |||
return names.toArray(new String[names.size()]); |
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.
Can't we write it using method reference as return names.toArray(String[]::new) ?
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, I don't think so. AFAIK, you can't create an array using that syntax. Even if you could, it would presumably give you a 0-length array which would defeat the purpose of the change that @izeye is proposing.
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.
@wilkinsona You are correct, I mistook it
Afaik a sized array is not always the fastest solution. When using a sized array the VM needs to initialize it with all zeroes, so it will be inited twice. When using a unsized array the VM can omit the |
@joshiste Thanks for the feedback! I didn't intend to gain better performance via this change but tried to align them with the other parts in codebase and simply avoid unnecessary empty array creation. By the way I'm curious on the double initialization part from your comment. Could you explain more on it as I don't understand where the double initialization is coming from? |
FWIW, I don't understand either. If the passed in array is too small, a new array is initialized reflectively. Once armed with an appropriate array, |
I've just done a simple JMH on this. https://gist.github.com/joshiste/9c49661be53b752b36042b05581dbf20 Results:
|
Imho this proves (for smaller array sizes) that calling toArray(new String[0]) yields the highest throughput. |
@joshiste Thanks for the feedback! I found a few articles backing your feedback like this one: https://shipilev.net/blog/2016/arrays-wisdom-ancients/ I didn't read them thoroughly yet but based on the articles the opposite direction of this PR looks right. I'll look into it soon. |
I always preferred the syntax of the zero-array better. I've raised #12160 to switch to it. |
My explanation wasn't quite correct... If the toArray() method instantiates the array itself it can completely omit the initialisation of the array as it knows that it will set the complete content. |
I did read the above mentioned article closely and I think I understand the benchmark result better now which looks counter-intuitive at first glance. I'd recommend anyone interested in this topic to read the article. @joshiste Thanks for enlightening me on this! |
This PR changes to use sized array for
List.toArray()
.