Skip to content
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

Restructure ListBuffer to build and insert chains #9257

Merged
merged 1 commit into from Nov 23, 2020

Conversation

NthPortal
Copy link
Contributor

@NthPortal NthPortal commented Oct 22, 2020

Restructure ListBuffer to build fresh ListBuffers and
then insert them into the existing chain.

Fixes calling ListBuffer#patchInPlace with itself
(scala/bug#12121).

Follow-up to #9174

Restructure `ListBuffer` to build fresh `ListBuffer`s and
then insert them into the existing chain.

Fixes calling `ListBuffer#patchInPlace` with itself
([bug#12121]).
@NthPortal NthPortal added the library:collections PRs involving changes to the standard collection library label Oct 22, 2020
@scala-jenkins scala-jenkins added this to the 2.13.4 milestone Oct 22, 2020
@dwijnand dwijnand modified the milestones: 2.13.4, 2.13.5 Oct 23, 2020
@dwijnand
Copy link
Member

dwijnand commented Nov 9, 2020

@joshlemer / @Ichoran would either of you like to review this?

Copy link
Contributor

@Ichoran Ichoran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good...I think there's an opportunity to clean up the code a little bit, but it's not particularly important. As far as I can tell by eye, it looks correct and should perform well and fix self-addition problems.

val it = xs.iterator
if (it.hasNext) {
ensureUnaliased()
// MUST only be called on fresh instances
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the only possible use is to call it on a fresh instance, why not create the instance too? Otherwise, doesn't it just expose a risk of mis-use while requiring more boilerplate at the call site?

@@ -407,7 +395,7 @@ class ListBuffer[A]
@SerialVersionUID(3L)
object ListBuffer extends StrictOptimizedSeqFactory[ListBuffer] {

def from[A](coll: collection.IterableOnce[A]): ListBuffer[A] = new ListBuffer[A] ++= coll
def from[A](coll: collection.IterableOnce[A]): ListBuffer[A] = new ListBuffer[A].freshFrom(coll)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you never use freshFrom to do anything but this, why not just use from? Is this to avoid possible overhead from checking the initialization of the companion object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what the overhead is from, but back when I was benchmarking #9174, I discovered that from had significantly worse performance than new (with ++= I think). if someone has a more reliable benchmarking setup and wants to run it again, that'd be great. that was my primary motivation for using new and a private method

@SethTisue SethTisue merged commit 024a21f into scala:2.13.x Nov 23, 2020
@NthPortal NthPortal deleted the topic/ListBuffer-restructure/PR branch November 23, 2020 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
library:collections PRs involving changes to the standard collection library
Projects
None yet
6 participants