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

Devoxx UK 2015 Presentation: Miniboxing - Fast Generics for Primitive Types

Devoxx UK 2015 Presentation: Miniboxing - Fast Generics for Primitive Types

Miniboxing presentation at Devoxx UK 2015. Website: http://www.devoxx.co.uk/

The recording is available on parleys: https://www.parleys.com/tutorial/miniboxing-fast-generics-primitive-types

The two demos:
- Streams: not yet online
- Image processing: http://scala-miniboxing.org/example_pureimage.html

Project website: http://scala-miniboxing.org

456d1d6154efe50e950b65f966f63a50?s=128

Vlad Ureche

June 18, 2015
Tweet

Transcript

  1. scala-miniboxing.org @miniboxing 18th of June 2015 Devoxx United Kingdom London,

    UK scala-miniboxing.org
  2. scala-miniboxing.org @miniboxing Vlad URECHE PhD student in the Scala Team

    @ EPFL Working on program transformations in the Scala programming language, focusing on data representation. Contributions to specialization, backend and Scaladoc. @ @VladUreche @VladUreche vlad.ureche@epfl.ch
  3. scala-miniboxing.org @miniboxing scala-miniboxing.org

  4. scala-miniboxing.org @miniboxing STOP Please ask if things are not clear!

  5. scala-miniboxing.org @miniboxing STOP Please ask if things are not clear!

    Really! I mean it!
  6. scala-miniboxing.org @miniboxing What is miniboxing? Why use it? How does

    it... ? Conclusion Generics
  7. scala-miniboxing.org @miniboxing Compilers Compilers

  8. scala-miniboxing.org @miniboxing Compilers Compilers Source code (language 1) compiler C,

    C++, Java, Scala, C#, Haskell, Clojure, ...
  9. scala-miniboxing.org @miniboxing Compilers Compilers Source code (language 1) Source code

    (language 2) compiler C, C++, Java, Scala, C#, Haskell, Clojure, ... x86/ARM assembly LLVM bitcode Cuda code JVM bytecode .NET bytecode ...
  10. scala-miniboxing.org @miniboxing Compilers Compilers Source code (language 1) Source code

    (language 2) compiler C, C++, Java, Scala, C#, Haskell, Clojure, ... x86/ARM assembly LLVM bitcode Cuda code JVM bytecode .NET bytecode ... Why so much fuss ?
  11. scala-miniboxing.org @miniboxing Compilers Compilers Abstraction Imple- mentation compiler

  12. scala-miniboxing.org @miniboxing Compilers Compilers Abstraction Imple- mentation compiler Variable

  13. scala-miniboxing.org @miniboxing Compilers Compilers Abstraction Imple- mentation compiler Variable Stack

    slot or Processor register or Heap location
  14. scala-miniboxing.org @miniboxing Compilers Compilers Abstraction Imple- mentation compiler Variable Stack

    slot or Processor register or Heap location … Implementation details
  15. scala-miniboxing.org @miniboxing Generics Don't Exist Generics Don't Exist in the

    JVM in the JVM
  16. scala-miniboxing.org @miniboxing Generics Don't Exist Generics Don't Exist in the

    JVM in the JVM Java/ Scala
  17. scala-miniboxing.org @miniboxing Generics Don't Exist Generics Don't Exist in the

    JVM in the JVM Java/ Scala
  18. scala-miniboxing.org @miniboxing Generics Don't Exist Generics Don't Exist in the

    JVM in the JVM Javac Scalac Java/ Scala
  19. scala-miniboxing.org @miniboxing Generics Don't Exist Generics Don't Exist in the

    JVM in the JVM Javac Scalac Generics Java/ Scala
  20. scala-miniboxing.org @miniboxing Erased Generics Erased Generics def identity[T](t: T): T

    = t
  21. scala-miniboxing.org @miniboxing Erased Generics Erased Generics def identity[T](t: T): T

    = t scalac / javac
  22. scala-miniboxing.org @miniboxing Erased Generics Erased Generics def identity[T](t: T): T

    = t def identity(t: Object): Object = t scalac / javac
  23. scala-miniboxing.org @miniboxing Erased Generics Erased Generics identity(5)

  24. scala-miniboxing.org @miniboxing Erased Generics Erased Generics identity(5) 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 Object 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
  28. 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
  29. 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)
  30. 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
  31. scala-miniboxing.org @miniboxing Specialization Specialization Iulian Dragoș (@jaguarul) (circa 2009)

  32. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

  33. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    specialization
  34. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization
  35. 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
  36. 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
  37. 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)
  38. scala-miniboxing.org @miniboxing Specialization Specialization identity(5)

  39. scala-miniboxing.org @miniboxing Specialization Specialization identity(5) specialization

  40. scala-miniboxing.org @miniboxing Specialization Specialization identity(5) identity_I(5) specialization

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

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

    ...
  43. scala-miniboxing.org @miniboxing Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... specialization
  44. scala-miniboxing.org @miniboxing Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

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

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

    ... // 100 methods (102) specialization Can we do better?
  47. scala-miniboxing.org @miniboxing What is miniboxing? Why use it? How does

    it... ? Conclusion Generics
  48. scala-miniboxing.org @miniboxing The idea behind The idea behind LONG miniboxing

    miniboxing
  49. scala-miniboxing.org @miniboxing The idea behind The idea behind LONG DOUBLE

    miniboxing miniboxing
  50. scala-miniboxing.org @miniboxing The idea behind The idea behind LONG DOUBLE

    INT miniboxing miniboxing
  51. scala-miniboxing.org @miniboxing The idea behind The idea behind ... LONG

    DOUBLE INT FLOAT SHORT miniboxing miniboxing
  52. 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
  53. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

  54. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    miniboxing
  55. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing
  56. 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
  57. 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
  58. 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
  59. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3)

  60. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3) miniboxing

  61. scala-miniboxing.org @miniboxing Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing

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

    variant of identity
  63. 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
  64. scala-miniboxing.org @miniboxing

  65. scala-miniboxing.org @miniboxing What is miniboxing? Why use it? How does

    it... ? Conclusion Generics
  66. scala-miniboxing.org @miniboxing

  67. scala-miniboxing.org @miniboxing Speedups

  68. scala-miniboxing.org @miniboxing Speedups Performance advisories

  69. scala-miniboxing.org @miniboxing DEMO

  70. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

  71. scala-miniboxing.org @miniboxing

  72. scala-miniboxing.org @miniboxing

  73. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens
  74. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET
  75. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET • … but Scala did not have streaming support
  76. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET • But Scala lacks an equivalent streaming support – Thus the numbers :)
  77. scala-miniboxing.org @miniboxing In the meantime... he implemented it

  78. scala-miniboxing.org @miniboxing

  79. scala-miniboxing.org @miniboxing DEMO

  80. scala-miniboxing.org @miniboxing

  81. scala-miniboxing.org @miniboxing What is miniboxing? Why use it? How does

    it... ? Conclusion Generics
  82. scala-miniboxing.org @miniboxing Warnings Warnings scala> def baz[T](t: T): T =

    t baz: [T](t: T)T scala> baz(4)
  83. scala-miniboxing.org @miniboxing Warnings Warnings scala> def baz[T](t: T): T =

    t baz: [T](t: T)T scala> baz[Int](4)
  84. scala-miniboxing.org @miniboxing Warnings Warnings scala> def baz[T](t: T): T =

    t baz: [T](t: T)T scala> baz[Int](4) <console>:9: warning: The method baz would benefit from miniboxing type parameter T, since it is instantiated by a primitive type. ...
  85. scala-miniboxing.org @miniboxing Call Graph Call Graph def foo[T](t: T): T

    = bar(t)
  86. scala-miniboxing.org @miniboxing Call Graph Call Graph def foo[T](t: T): T

    = bar(t) def bar[T](t: T): T = baz(t)
  87. 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
  88. 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
  89. scala-miniboxing.org @miniboxing Call Graph Call Graph foo

  90. scala-miniboxing.org @miniboxing Call Graph Call Graph foo bar

  91. scala-miniboxing.org @miniboxing Call Graph Call Graph foo bar baz

  92. 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
  93. 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
  94. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo(...):

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

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

    bar bar_M baz baz_M Data is pased in the miniboxed encoding no boxing necessary!
  97. 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
  98. 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
  99. 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
  100. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

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

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

    bar baz baz_M boxing arguments → warn
  103. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M boxing arguments → warn
  104. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M boxing arguments → warn
  105. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M boxing arguments → warn there is a better version but I can't call it → warn
  106. 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
  107. scala-miniboxing.org @miniboxing Warnings Warnings • Miniboxing tries to avoid boxing

    • When it can't avoid it, it warns you – And you can act on it • Many other warnings – To keep you from shooting yourself in the foot
  108. scala-miniboxing.org @miniboxing

  109. scala-miniboxing.org @miniboxing Who's that JVM performance expert over there?

  110. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes ... library ... library
  111. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes • Adds – Interfaces to other constructs – Miniboxed state reflection ... library ... library
  112. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes • Adds – Interfaces to other constructs – Miniboxed state reflection ... library ... library Am I inside a miniboxed class? If so, what is T?
  113. scala-miniboxing.org @miniboxing What is miniboxing? Why use it? How does

    it... ? Conclusion Generics
  114. scala-miniboxing.org @miniboxing

  115. scala-miniboxing.org @miniboxing

  116. scala-miniboxing.org @miniboxing

  117. scala-miniboxing.org @miniboxing

  118. scala-miniboxing.org @miniboxing

  119. scala-miniboxing.org @miniboxing

  120. scala-miniboxing.org @miniboxing

  121. scala-miniboxing.org @miniboxing scala-miniboxing.org

  122. scala-miniboxing.org @miniboxing scala-miniboxing.org

  123. scala-miniboxing.org @miniboxing scala-miniboxing.org tutorials

  124. scala-miniboxing.org @miniboxing scala-miniboxing.org tutorials sbt config

  125. scala-miniboxing.org @miniboxing scala-miniboxing.org tutorials sbt config examples

  126. scala-miniboxing.org @miniboxing scala-miniboxing.org tutorials sbt config examples support

  127. scala-miniboxing.org @miniboxing Credits and Thank you-s • Martin Odersky -

    without Scala, there would be no miniboxing • Cristian Talau - developed the initial prototype, as a semester project • Milos Stojanovic - work on warnings, tuple accessors and others • Romain Beguet - work on miniboxed arrays • Eugene Burmako - the value class plugin based on the LDL transformation • Aymeric Genet - developing collection-like benchmarks for the miniboxing plugin • Martin Odersky, for his patient guidance • Dmitry Petrashko, for the many cool discussions we had • Ilya Klyuchnikov and Pablo Guerrero - fixes and commits • Iulian Dragos, for his work on specialization and many explanations • Miguel Garcia, for his original insights that spawned the miniboxing idea • Michel Schinz, for his wonderful comments and enlightening ACC course • Andrew Myers and Roland Ducournau for the discussions we had and the feedback provided • Heather Miller for the eye-opening discussions we had • Vojin Jovanovic, Sandro Stucki, Manohar Jonalagedda and the whole LAMP laboratory in EPFL • Adriaan Moors, for the miniboxing name which stuck :)) • Thierry Coppey, Vera Salvisberg and George Nithin, for the feedback
  128. scala-miniboxing.org @miniboxing Credits and Thank you-s • Grzegorz Kossakowski, for

    the many brainstorming sessions on specialization • Erik Osheim, Tom Switzer and Rex Kerr for their guidance on the Scala community side • Sandro, Vojin, Nada, Heather, Manohar - reviews and discussions on the LDL paper • Hubert Plociniczak for the type notation in the LDL paper • Denys Shabalin (@densh), Dmitry Petrashko (@darkdimius) for their patient reviews of the LDL paper • Alexandru Nedelcu (@alex_ndc) - for the functions direction • Stu Hood (@stuhood) - for the initial support, ideas • Julien Truffault (@JulienTruffaut) - for motivating the development of tuple accessors, sticky plugin warnings • Aggelos Biboudis (@biboudis) - for pushing the functions project forward and the stream benchmarks • Tom Switzer (@tixxit) - for pushing the array project forward and the vector benchmarks • Philip Stutz (@PhilipStutz) - for the ideas on warnings • Rex Kerr (@ichoran) - for ideas on reflection • Vlad Patryshev (@vpatryshev) - for organizing the Scala Bay Meetup, wehre I presented once • The Scala Community • The Valhalla Project Architects • The Devoxx, PNWScala and ScalaDays organizers!
  129. scala-miniboxing.org @miniboxing scala-miniboxing.org Thank you!

  130. scala-miniboxing.org @miniboxing

  131. scala-miniboxing.org @miniboxing

  132. scala-miniboxing.org @miniboxing scala-miniboxing.org

  133. scala-miniboxing.org @miniboxing http://stephenjudkins.github.io/pureimage-presentation/#/

  134. scala-miniboxing.org @miniboxing http://stephenjudkins.github.io/pureimage-presentation/#/32

  135. scala-miniboxing.org @miniboxing PureImage PureImage • has very nice abstractions –

    generalizes over input, output format – generalizes over pixel format – provides collection-like mapping over images • liked it a lot
  136. scala-miniboxing.org @miniboxing PureImage PureImage • took the usual path to

    using miniboxing – code up a mock-up – become familiar with the problem – try out miniboxing on a small scale
  137. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up

  138. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Image[Repr: Pixel]

    { def width: Int def height: Int def apply(x: Int, y: Int): Repr def map[Repr2: Pixel](f: Image[Repr] => Generator[Repr2]): Image[Repr2] }
  139. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Image[Repr: Pixel]

    { def width: Int def height: Int def apply(x: Int, y: Int): Repr def map[Repr2: Pixel](f: Image[Repr] => Generator[Repr2]): Image[Repr2] } What's a generator?
  140. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Generator[Repr: Pixel]

    { def width: Int def height: Int def generate(x: Int, y: Int): Repr }
  141. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Generator[Repr: Pixel]

    { def width: Int def height: Int def generate(x: Int, y: Int): Repr } Why generic? What is pixel?
  142. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors
  143. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels
  144. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels
  145. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Transformed image 8-bit RGBA channels ...
  146. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ...
  147. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts
  148. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA
  149. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA discretization only when saving the file => better quality
  150. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA discretization only when saving the file => better quality Pixel representation
  151. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... }
  152. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... } All transformations occur on doubles
  153. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... } All transformations occur on doubles But the data can be encoded differently
  154. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... }
  155. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } Encoding all channels
  156. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } case class DiscreteChannels[T](r: T, g: T, b: T, a: T) object FullPixel extends FourChannelPixel[Double] object HalfPixel extends FourChannelPixel[Float] Encoding all channels
  157. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } case class DiscreteChannels[T](r: T, g: T, b: T, a: T) object FullPixel extends FourChannelPixel[Double] object HalfPixel extends FourChannelPixel[Float] Storing channels individually Encoding all channels
  158. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up

  159. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up "More London Office Development

    at Dusk, London, UK - Diliff" by Diliff - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:More_London_Office_Development_at_Dusk,_London,_UK_-_Diliff.jpg
  160. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up "More London Office Development

    at Dusk, London, UK - Diliff" by Diliff - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:More_London_Office_Development_at_Dusk,_London,_UK_-_Diliff.jpg
  161. scala-miniboxing.org @miniboxing scala-miniboxing.org Last example is at http://scala-miniboxing.org/example_pureimage.html