Skip to content

Conversation

@retronym
Copy link
Member

Boxing and varargs incur a significant penalty for string
interpolation, as explored in:

https://medium.com/@dkomanov/scala-string-interpolation-performance-21dc85e83afd

This pull request takes an initial, big step back towards decent performance
by translating calls to these interpolators to string concatenation, which
itself is already translated to string builder appends in the JVM backend.

I have also tried to be a little smarter with the way we size the string
builder.

Longer term, we should build atop of JEP-280 to extract even better
performance with less code for us to maintain. But that's not available
until Java 9.

@scala-jenkins scala-jenkins added this to the 2.12.5 milestone Sep 22, 2017
@lrytz
Copy link
Member

lrytz commented Sep 23, 2017

JavaUniverseForce.scala must be updated.
===========================================================
 DIFF:
===========================================================
--- a
+++ b
@@ -321,2 +321,3 @@
     definitions.StringContextClass
+    definitions.StringContextModule
     definitions.QuasiquoteClass

Also the following, which I cannot pin down by just looking at the jenkins log:

[error] - junit/test
[error]   - junit/test:compileIncremental failed: scala.StringContext$InvalidEscapeException: invalid escape '\x' not one of [\b, \t, \n, \f, \r, \\, \", \'] at index 0 in "\x". Use \\ for literal \.

@retronym
Copy link
Member Author

retronym commented Sep 25, 2017

Fixed up the test failure and refactored the implementation some.

I'm happy with the 2.12.5 milestone for this one, seems too risky to rush in to 2.12.4.

val experimental: NameType = "experimental"
val f: NameType = "f"
val s: NameType = "s"
val raw_ : NameType = "raw"
Copy link
Member

Choose a reason for hiding this comment

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

alphabetical order?

Copy link
Member

Choose a reason for hiding this comment

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

no strong opinion, but it seems the others here are alphabetical indeed.

@retronym retronym changed the title WIP Intrinsfy raw and s interpolators Intrinsfy raw and s String interpolators Dec 1, 2017
@retronym retronym requested a review from lrytz January 15, 2018 04:28
@retronym
Copy link
Member Author

@lrytz Are you happy with the final state of this to target 2.12.5?

Copy link
Member

@lrytz lrytz 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, only a few cosmetic cleanups.

lazy val StringContext_f = getMemberMethod(StringContextClass, nme.f)
lazy val StringContext_s = getMemberMethod(StringContextClass, nme.s)
lazy val StringContext_raw = getMemberMethod(StringContextClass, nme.raw_)
lazy val StringContext_constructor = getMemberMethod(StringContextClass, nme.CONSTRUCTOR)
Copy link
Member

Choose a reason for hiding this comment

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

this is unused

val experimental: NameType = "experimental"
val f: NameType = "f"
val s: NameType = "s"
val raw_ : NameType = "raw"
Copy link
Member

Choose a reason for hiding this comment

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

no strong opinion, but it seems the others here are alphabetical indeed.


def mkLiteralUnit: Literal = Literal(Constant(()))
def mkUnitBlock(expr: Tree): Block = Block(List(expr), mkLiteralUnit)
def mkLiteralString(s: String): Literal = Literal(Constant(s)).setType(StringTpe)
Copy link
Member

Choose a reason for hiding this comment

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

unused

}

private object StringContextIntrinsic {
def unapply(t: Apply): Option[(List[Tree], List[Tree])] = {
Copy link
Member

Choose a reason for hiding this comment

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

Could return an Option[(List[Literal], List[Tree])] to avoid the casts at the use site, though it would require another map in the raw case. Up to you, both ways is fine.

transform(qual)

case StringContextIntrinsic(treated, args) =>
var tree: Tree = treated.head
Copy link
Member

Choose a reason for hiding this comment

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

maybe call it result to avoid shadowing (and confusion)

@lrytz lrytz added the release-notes worth highlighting in next release notes label Feb 23, 2018
@lrytz lrytz self-assigned this Feb 23, 2018
Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

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

pushed my review suggestions

@lrytz
Copy link
Member

lrytz commented Feb 23, 2018

/synch

@retronym
Copy link
Member Author

retronym commented Mar 5, 2018

pushed my review suggestions

Thanks!

@SethTisue
Copy link
Member

questions: this is intrinsics and not a macro in order to get it into 2.12.x, because bincompat...? and the motivation for getting it into 2.12.x instead of just waiting for 2.13.x is compiler performance...?

@retronym
Copy link
Member Author

retronym commented Mar 15, 2018 via email

@SethTisue
Copy link
Member

Nice, forgot about 475! Thx /cc @hrhino

@xuwei-k
Copy link
Contributor

xuwei-k commented May 9, 2018

scala/bug#10870 😢

@eed3si9n
Copy link
Member

eed3si9n commented Oct 9, 2018

scala/bug#11196

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes worth highlighting in next release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants