Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Miniboxing Library - Scala.world

456d1d6154efe50e950b65f966f63a50?s=47 Vlad Ureche
September 13, 2016

Miniboxing Library - Scala.world

Miniboxing Library - Scala.world

456d1d6154efe50e950b65f966f63a50?s=128

Vlad Ureche

September 13, 2016
Tweet

Transcript

  1. scala-miniboxing.org @miniboxing 12th of September 2016 scala.world Penrith, UK The

    Story of a Parallel Scala Library
  2. scala-miniboxing.org @miniboxing The Story of a Parallel Scala Library The

    constructs used by miniboxing to optimize your code 12th of September 2016 scala.world Penrith, UK
  3. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Compiler transformation

  4. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Compiler transformation • Improves performance

    of generics – When instantiated by primitive types
  5. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Compiler transformation • Improves performance

    of generics – When instantiated by primitive types • Introduces optimized constructs – Automatically – Or with programmer help
  6. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Compiler transformation • Improves performance

    of generics – When instantiated by primitive types • Introduces optimized constructs – Automatically – Or with programmer help
  7. scala-miniboxing.org @miniboxing STOP Please ask if things are not clear!

  8. scala-miniboxing.org @miniboxing Motivation Motivation • We build cool new constructs

    and paradigms for { conn getConnection \/> "Could not connect" ← ids conn.get("id") \/> "Coult not get ids" ← } yield user
  9. scala-miniboxing.org @miniboxing Motivation Motivation • We build cool new constructs

    and paradigms • But some constructs are deeply integrated • Functions • Tuples • Arrays • Ordering • Numeric for { conn getConnection \/> "Could not connect" ← ids conn.get("id") \/> "Coult not get ids" ← } yield user
  10. scala-miniboxing.org @miniboxing Motivation Motivation val x = (x: Int) =>

    x
  11. scala-miniboxing.org @miniboxing Motivation Motivation val x = (x: Int) =>

    x Function syntax is sugar for anonymous classes extending FunctionX traits (or for Java8 lambdas)
  12. scala-miniboxing.org @miniboxing Motivation Motivation val x = (x: Int) =>

    x Extending Function1 behavior? Sure, add an implicit. Function syntax is sugar for anonymous classes extending FunctionX traits (or for Java8 lambdas)
  13. scala-miniboxing.org @miniboxing Motivation Motivation val x = (x: Int) =>

    x Extending Function1 behavior? Sure, add an implicit. Changing behavior (e.g. PartialFunction)? This is what we'll talk about today. Function syntax is sugar for anonymous classes extending FunctionX traits (or for Java8 lambdas)
  14. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class
  15. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface
  16. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature
  17. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method
  18. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method Changing the fields of a class
  19. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method Changing the fields of a class Extending behavior Changing behavior
  20. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Why would you need that? Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method Changing the fields of a class Extending behavior Changing behavior
  21. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  22. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  23. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  24. scala-miniboxing.org @miniboxing Erased Generics Erased Generics def identity[T](t: T): T

    = t def identity(t: Object): Object = t scalac / javac
  25. scala-miniboxing.org @miniboxing Erased Generics Erased Generics identity(5) identity(java.lang.Integer.valueOf(5)) scalac /

    javac
  26. scala-miniboxing.org @miniboxing Erased Generics Erased Generics identity(5) identity(java.lang.Integer.valueOf(5)) scalac /

    javac boxed data representation
  27. scala-miniboxing.org @miniboxing Erased Generics Erased Generics java.lang.Integer.valueOf(5) boxing is not

    great ... boxing is not great ... inflates heap requirements produces garbage value is accessed indirectly (slow) breaks locality guarantees
  28. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t
  29. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t
  30. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t … (7 other variants)
  31. scala-miniboxing.org @miniboxing Specialization Specialization identity(5) identity_I(5) specialization

  32. scala-miniboxing.org @miniboxing Specialization Specialization identity(5) identity_I(5) specialization No boxing, it

    automatically calls the specialized variant for integers
  33. scala-miniboxing.org @miniboxing Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization
  34. scala-miniboxing.org @miniboxing Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization Can we do better?
  35. scala-miniboxing.org @miniboxing The idea behind The idea behind ... LONG

    DOUBLE INT FLOAT SHORT ... LONG DOUBLE INT FLOAT SHORT a long integer miniboxing miniboxing
  36. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t
  37. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t long encodes all primitive types
  38. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t Only 2n variants long encodes all primitive types
  39. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing

  40. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing The miniboxed

    variant of identity
  41. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing The miniboxed

    variant of identity Unlike boxing, these conversions do not affect performance
  42. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  43. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  44. scala-miniboxing.org @miniboxing Call Graph Call Graph def foo[T](t: T): T

    = bar(t) def bar[T](t: T): T = baz(t) def baz[T](t: T): T = t call graph
  45. scala-miniboxing.org @miniboxing Call Graph Call Graph foo bar baz

  46. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t miniboxing
  47. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo(...):

    ... = bar(...) def foo_M(...): ... = bar_M(...) def bar(...): ... = baz(...) def bar_M(...): ... = baz_M(...) def baz(...): ... = t def baz_M(...): ... = t
  48. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph foo foo_M

    bar bar_M baz baz_M
  49. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph foo foo_M

    bar bar_M baz baz_M Data is passed in the miniboxed encoding no boxing necessary!
  50. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t miniboxing
  51. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M
  52. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M no bar_M to call box →
  53. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M no bar_M to call box →
  54. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M no bar_M to call box →
  55. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M no bar_M to call box → not enough info to return to the optimized trace
  56. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph scala> object

    Test { | def foo[@miniboxed T](t: T): T = bar(t) | def bar[ T](t: T): T = baz(t) | def baz[@miniboxed T](t: T): T = t | } <console>:10: warning: The method Test.bar would benefit from miniboxing type parameter T, since it is instantiated by miniboxed type parameter T of method foo: def foo[@miniboxed T](t: T): T = bar(t) ^ <console>:11: warning: The following code could benefit from miniboxing specialization if the type parameter T of method bar would be marked as "@miniboxed T": def bar[T](t: T): T = baz(t) ^ defined object Test
  57. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  58. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  59. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[T] =

    (t: T) => t defined method identityFun
  60. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[T] =

    (t: T) => t defined method identityFun scala> identityFun(3) <console>:11: warning: The method identityFun would benefit from miniboxing type parameter T, since it is instantiated by a primitive type. identityFun(3) ^ res1: Int = 3
  61. scala-miniboxing.org @miniboxing scala> def identityFun[@miniboxed T] = (t: T) =>

    t Library Interoperation Library Interoperation
  62. scala-miniboxing.org @miniboxing scala> def identityFun[@miniboxed T] = (t: T) =>

    t <console>:12: warning: The type parameter T1 of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ <console>:12: warning: The type parameter R of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ defined method identityFun Library Interoperation Library Interoperation
  63. scala-miniboxing.org @miniboxing scala> def identityFun[@miniboxed T] = (t: T) =>

    t <console>:12: warning: The type parameter T1 of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ <console>:12: warning: The type parameter R of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ defined method identityFun Library Interoperation Library Interoperation Not actionable
  64. scala-miniboxing.org @miniboxing scala> def identityFun[@miniboxed T] = (t: T) =>

    t <console>:12: warning: The type parameter T1 of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ <console>:12: warning: The type parameter R of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ defined method identityFun Library Interoperation Library Interoperation Not actionable Need to fix it
  65. scala-miniboxing.org @miniboxing scala> def identityFun[@miniboxed T] = (t: T) =>

    t <console>:12: warning: The type parameter T1 of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ <console>:12: warning: The type parameter R of trait scala.Function1 is specialized but to interoperate efficiently with miniboxing, it would have to be miniboxed. def identityFun[@miniboxed T] = (t: T) => t ^ defined method identityFun Library Interoperation Library Interoperation Not actionable Need to fix it
  66. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation • Multiple such constructs

    – Functions automatic, most interesting → – Arrays need user intervention, warnings → – Tuples automatic → – Numeric automatic, but I was lazy →
  67. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Data Representation Mixing

    Representations Library Interoperation
  68. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  69. scala-miniboxing.org @miniboxing MbFunctionX MbFunctionX • Miniboxed replacement for FunctionX •

    Assumptions – Function created once – Called multiple times optimize for calling → overhead
  70. scala-miniboxing.org @miniboxing MbFunctionX MbFunctionX • Miniboxed replacement for FunctionX •

    Assumptions – Function created once – Called multiple times optimize for calling → overhead Let's see how we transform
  71. scala-miniboxing.org @miniboxing MbFunctionX MbFunctionX • Three approaches – trait Function0[@miniboxed

    @specialized R] • Incompatible transformations, won't fly – Call-site adaptation (implicit + value class) • call overhead – Replace FunctionX body • no call overhead
  72. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[@miniboxed T]

    = (t: T) => t defined method identityFun
  73. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[@miniboxed T]

    = (t: T) => t defined method identityFun def identityFun[@miniboxed T]: MbFunction1[T, T] = ...
  74. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[@miniboxed T]

    = (t: T) => t defined method identityFun def identityFun[@miniboxed T]: MbFunction1[T, T] = ... Once this is done, miniboxing does its magic
  75. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation scala> def identityFun[@miniboxed T]

    = (t: T) => t defined method identityFun def identityFun[@miniboxed T]: MbFunction1[T, T] = ... Once this is done, miniboxing does its magic def identityFun[T]: MbFunction1[T, T] = { class $anon extends MbFunction1_L[T, T] { def apply(t: T) = t } new $anon() } def identityFun_M[Tsp](...): MbFunction1[T, T] = { class $anon extends MbFunction1_M[T, T](...) { def apply_M(..., t: T) = t } new $anon() }
  76. scala-miniboxing.org @miniboxing Library Interoperation Library Interoperation • Multiple such constructs

    – Functions automatic, most interesting → – Arrays need user intervention, warnings → – Tuples automatic → – Numeric automatic, but I was lazy →
  77. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method Changing the fields of a class Extending behavior Changing behavior
  78. scala-miniboxing.org @miniboxing Extending vs Changing Behavior Extending vs Changing Behavior

    Adding a new method to the trait/class Making it conform to an interface Changing a method's signature Updating the body of a method Changing the fields of a class Extending behavior Changing behavior Completely replacing a library class
  79. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  80. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  81. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  82. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library

  83. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library Scala stdlib Other library

    Other library dependencies
  84. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library Scala stdlib Other library

    Other library dependencies
  85. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library Scala stdlib Other library

    Other library dependencies Each library is free to use its desired FunctionX version
  86. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library Scala stdlib Other library

    Other library dependencies Each library is free to use its desired FunctionX version Talk to each in its own "language"
  87. scala-miniboxing.org @miniboxing Dependencies Dependencies Your library Scala stdlib Other library

    Other library dependencies Each library is free to use its desired FunctionX version Talk to each in its own "language" Have to track of the transformations
  88. scala-miniboxing.org @miniboxing Marking Changes Marking Changes Source Signatures Bytecode Source

    Signatures Bytecode Source Signatures Bytecode JVM scalac scalac scalac
  89. scala-miniboxing.org @miniboxing Marking Changes Marking Changes Source Signatures Bytecode Source

    Signatures Bytecode Source Signatures Bytecode JVM scalac scalac scalac
  90. scala-miniboxing.org @miniboxing Marking Changes Marking Changes Source Signatures Bytecode Source

    Signatures Bytecode Source Signatures Bytecode JVM scalac scalac scalac
  91. scala-miniboxing.org @miniboxing Marking Changes Marking Changes • Keep track of

    changes to – Methods – Fields – Classes – Traits • Carry transformation info with types – Automatically annotate the code – The pickler phase stores them in signatures – Introduce conversions where necessary
  92. scala-miniboxing.org @miniboxing Marking Changes Marking Changes

  93. scala-miniboxing.org @miniboxing Marking Changes Marking Changes

  94. scala-miniboxing.org @miniboxing Marking Changes Marking Changes

  95. scala-miniboxing.org @miniboxing Marking Changes Marking Changes place a compiler phase

    here
  96. scala-miniboxing.org @miniboxing Marking Changes Marking Changes def identityFun[@miniboxed T] =

    (t: T) => t typer
  97. scala-miniboxing.org @miniboxing Marking Changes Marking Changes def identityFun[@miniboxed T] =

    (t: T) => t def identityFun[@miniboxed T]: Function1[T, T] = (t: T) => t typer interop-inject
  98. scala-miniboxing.org @miniboxing Marking Changes Marking Changes def identityFun[@miniboxed T] =

    (t: T) => t def identityFun[@miniboxed T]: Function1[T, T] = (t: T) => t typer interop-inject @... def identityFun[@miniboxed T]: Function1[T, T] @mbFun = (t: T) => t pickler
  99. scala-miniboxing.org @miniboxing Marking Changes Marking Changes def identityFun[@miniboxed T] =

    (t: T) => t def identityFun[@miniboxed T]: Function1[T, T] = (t: T) => t typer interop-inject @... def identityFun[@miniboxed T]: Function1[T, T] @mbFun = (t: T) => t Future compilation runs are aware of the change pickler
  100. scala-miniboxing.org @miniboxing Conversions Conversions • What do to if –

    We have an MbFunction1 and – Callee expects Function1? • Conversions – Between the two cases – Functions defined in miniboxed code • Miniboxing-friendly and specialization-friendly – Functions defined in non-miniboxed code • Specialization-friendly • Need conversion Miniboxing friendly →
  101. scala-miniboxing.org @miniboxing Conversions Conversions def identityFun[@miniboxed T] = Predef.identity typer

  102. scala-miniboxing.org @miniboxing Conversions Conversions def identityFun[@miniboxed T] = Predef.identity def

    identityFun[@miniboxed T]: Function1[T, T] = Predef.identity[T] // : Function1[T, T] from classpath typer interop-inject
  103. scala-miniboxing.org @miniboxing Conversions Conversions def identityFun[@miniboxed T] = Predef.identity def

    identityFun[@miniboxed T]: Function1[T, T] = Predef.identity[T] // : Function1[T, T] from classpath typer interop-inject @... def identityFun[@miniboxed T]: Function1[T, T] @mbFun = Predef.identity[T] // : Function1[T, T] no annotation interop-coerce
  104. scala-miniboxing.org @miniboxing @... def identityFun[@miniboxed T]: Function1[T, T] @mbFun =

    toMbFun(Predef.identity[T]) // : Function1[T, T] @mbFun Conversions Conversions def identityFun[@miniboxed T] = Predef.identity def identityFun[@miniboxed T]: Function1[T, T] = Predef.identity[T] // : Function1[T, T] from classpath typer interop-inject @... def identityFun[@miniboxed T]: Function1[T, T] @mbFun = Predef.identity[T] // : Function1[T, T] no annotation interop-coerce
  105. scala-miniboxing.org @miniboxing Conversions Conversions Conversions are introduced based on types

    See scala-miniboxing.org/ldl for details
  106. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  107. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  108. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies Your library

  109. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies Your library Scala stdlib

    Other library Other library dependencies
  110. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies Your library Scala stdlib

    Other library Other library Other lib 1 Other lib 2 Other lib 3 dependencies reverse dependencies
  111. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies Your library Scala stdlib

    Other library Other library Other lib 1 Other lib 2 Other lib 3 dependencies reverse dependencies
  112. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies Your library Scala stdlib

    Other library Other library Other lib 1 Other lib 2 Other lib 3 dependencies reverse dependencies Libraries not compiled with the miniboxing plugin are not aware of the transformation → incorrect bytecode
  113. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies $ scala Welcome to

    Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101). Type in expressions to have them evaluated. Type :help for more information. scala> Test.identityFun(2) <console>:11: error: This method was compiled with the miniboxing plugin and can only be called by code also compiled with the miniboxing plugin (see scala-miniboxing.org/compatibility) [mbox=0.4-M8,scala=2.11.7] Test.identityFun(2) ^
  114. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies def identityFun[@miniboxed T] =

    (t: T) => t def identityFun[@miniboxed T]: Function1[T, T] = (t: T) => t typer interop-inject @compileTimeOnly(...) def identityFun[@miniboxed T]: Function1[T, T] @mbFun = (t: T) => t pickler
  115. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies def identityFun[@miniboxed T] =

    (t: T) => t def identityFun[@miniboxed T]: Function1[T, T] = (t: T) => t typer interop-inject @compileTimeOnly(...) def identityFun[@miniboxed T]: Function1[T, T] @mbFun = (t: T) => t Built into the Scala stdlib and recognized by scalac (checked by refchecks) pickler
  116. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies miniboxing introduces annotation here

  117. scala-miniboxing.org @miniboxing Reverse Dependencies Reverse Dependencies miniboxing introduces annotation here

    ... and removes it just before refchecks
  118. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  119. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  120. scala-miniboxing.org @miniboxing Object Model Object Model trait IdentityFun { def

    identityFun[T]: T => T // = Function1 [T, T] }
  121. scala-miniboxing.org @miniboxing Object Model Object Model trait IdentityFun { def

    identityFun[T]: T => T // = Function1 [T, T] } object MbIdentityFun extends IdentityFun { def identityFun[@miniboxed T]: T => T = (t: T) => t }
  122. scala-miniboxing.org @miniboxing Object Model Object Model trait IdentityFun { def

    identityFun[T]: T => T // = Function1 [T, T] } object MbIdentityFun extends IdentityFun { def identityFun[@miniboxed T]: T => T = (t: T) => t } scala> MbIdentityFun.identityFun(2) <console>:11: error: ... scala> val id: IdentityFun = MbIdentityFun id: IdentityFun = MbIdentityFun$@23223dd8 scala> id.identityFun(3) res1: Int = 3
  123. scala-miniboxing.org @miniboxing Object Model Object Model trait IdentityFun { def

    identityFun[T]: T => T // = Function1 [T, T] } object MbIdentityFun extends IdentityFun { def identityFun[@miniboxed T]: T => T = (t: T) => t } scala> MbIdentityFun.identityFun(2) <console>:11: error: ... scala> val id: IdentityFun = MbIdentityFun id: IdentityFun = MbIdentityFun$@23223dd8 scala> id.identityFun(3) res1: Int = 3 You can "hide" miniboxed code behind an interface
  124. scala-miniboxing.org @miniboxing Object Model Object Model • Allows "hiding" miniboxed

    code – Under an erased interface (example) – Under a specialized interface • Pro: no dependency on the plugin downstream • Cons: have to write some glue code
  125. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing Dependencies Reverse deps

    Object model
  126. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  127. scala-miniboxing.org @miniboxing RRBVector Experiment RRBVector Experiment • RRBVector is an

    immutable vector data structure – With constant-time split and merge (for parallel ops) • Idea by Phil Bagwell and Tiark Rompf • Implementation by Nicolas Stucki – 4 developer-weeks of work – Hand-tuned for maximum performance – Scaling almost linearly with the number of cores – Summing a vector is 2x as slow as summing an array • Presented at ICFP '15
  128. scala-miniboxing.org @miniboxing RRBVector Experiment RRBVector Experiment • Questions: – How

    difficult is it to specialize RRBVector with miniboxing? – What are the speedups obtained by miniboxing? • Preparation: – Copied the Scala stdlib suppor necessary for RRBVector (3k LOC) – Eliminated the parallel execution support (3k 2k LOC) → – Prepared benchmarks • Subject: Milos Stojanovic – Master student working in the lab – Experienced with miniboxing – Never saw the RRBVector code base before
  129. scala-miniboxing.org @miniboxing RRBVector Experiment RRBVector Experiment • It took 30

    minutes to optimize the code base by following the miniboxing warnings → 0.3% of the development time Benchmark Microbenchmarks (5M elements) Macrobenchmark Builder map fold reverse* Least squares linear regression (5M points) Erased (seconds) 43.2 103.0 94.1 31.4 4864.6 Miniboxed (seconds) 22.9 60.4 42.1 35.3 1818.1 Speedup (ratio) 1.88x 1.71x 2.24x 0.89x 2.68x * reversing a vector does not perform any operations that could benefit from miniboxing.
  130. scala-miniboxing.org @miniboxing RRBVector Experiment RRBVector Experiment • Used library features

    – MbFunction – MbArray – Tuples – Numeric – Ordering
  131. scala-miniboxing.org @miniboxing RRBVector Experiment RRBVector Experiment • Used library features

    – MbFunction – MbArray – Tuples – Numeric – Ordering Impossible to cover today
  132. scala-miniboxing.org @miniboxing

  133. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  134. scala-miniboxing.org @miniboxing Functions Transformation Experiment Conclusion Miniboxing

  135. scala-miniboxing.org @miniboxing Miniboxed Library Miniboxed Library • Replaces deeply integrated

    Scala constructs – Preserve the syntactic sugar – No source code changes • Scalac/miniboxing does a lot of the work • Use cases – Miniboxing: performance – <your use case here>
  136. scala-miniboxing.org @miniboxing scala-miniboxing.org Special thanks: Alexandru Nedelcu Milos Stojanovic Romain

    Beguet Nicolas Stucki Scala team @ EPFL