1 transient typechecks are almost free
play

1 Transient Typechecks are (almost) Free Richard Roberts, Stefan - PowerPoint PPT Presentation

1 Transient Typechecks are (almost) Free Richard Roberts, Stefan Marr Michael Homer, James Noble 2 Transient Performance The transient approach checks types at uses, so the act of adding types to a program introduces more


  1. � 1

  2. Transient 
 Typechecks 
 are (almost) Free Richard Roberts, Stefan Marr 
 Michael Homer, James Noble 2

  3. Transient Performance “ The transient approach checks types at uses, so the act of adding types to a program introduces more casts and may slow the program down (even in fully typed code). ” … “transient semantics...is a worst case scenario ..., there is a cast at almost every call” Chung, Li, Nardelli and Vitek, ECOOP 2018 “ imposes a run-time checking overhead that is directly proportional to the number of [type annotations] in the program ” Greenman and Felleisen, ICFP 2018 “ clear trend that adding type annotations adds performance overhead. The increase is typically linear . ” Greenman and Migeed, PEPM 2018 3

  4. Microbenchmarks method foo9(xa : A, xb : B, xc : C, xd : D, xe : E) { count := count + 1 foo8(a,b,c,d,e) } method foo8(xa : A, xb : B, xc : C, xd : D, xe : E) { count := count + 1 foo7(a,b,c,d,e) } method foo7(xa : A, xb : B, xc : C, xd : D, xe : E) { count := count + 1 foo6(a,b,c,d,e) } 4

  5. Microbenchmarks method foo9(xa , xb , xc , xd , xe ) { count := count + 1 foo8(a,b,c,d,e) } method foo8(xa , xb , xc , xd , xe ) { count := count + 1 foo7(a,b,c,d,e) } method foo7(xa , xb , xc , xd , xe ) { count := count + 1 foo6(a,b,c,d,e) } 5

  6. Microbenchmarks method foo9(xa : A, xb : B, xc : C, xd , xe ) { count := count + 1 foo8(a,b,c,d,e) } method foo8(xa : A, xb : B, xc : C, xd , xe ) { count := count + 1 foo7(a,b,c,d,e) } method foo7(xa : A, xb : B, xc : C, xd , xe ) { count := count + 1 foo6(a,b,c,d,e) } 6

  7. Microbenchmarks method foo9(xa : A, xb : B, xc : C, xd : D, xe : E) { count := count + 1 foo8(a,b,c,d,e) } method foo8(xa : A, xb : B, xc : C, xd : D, xe : E) { count := count + 1 foo7(a,b,c,d,e) } method foo7(xa , xb , xc , xd , xe ) { count := count + 1 foo6(a,b,c,d,e) } 7

  8. Are We Fast Yet? Iteration 1 Check Nest 3200 2800 (lower is better) Run time (ms) 2400 2000 0 1 2 3 4 5 0 1 2 3 4 5 Number of Typed Method Arguments 8

  9. Are We Fast Yet? Iteration 1 Iteration 100 Check Nest Check Nest 800 3200 Moth (both) Moth (neither) Moth (untyped) 600 2800 (lower is better) (lower is better) Run time (ms) Run time (ms) 400 2400 200 2000 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 Number of Typed Method Arguments Number of Typed Method Arguments 9

  10. Transient 
 Typechecks 
 are (almost) Free Richard Roberts, Stefan Marr 
 Michael Homer, James Noble 10

  11. � 11

  12. Grace 12

  13. Goals Not require type annotations Dynamic types must be checked Checking must be cheap Run statically incorrect code Lightweight Implementation 13

  14. 14

  15. Grace Every object has a class Everything is an object Methods, fields, constants Methods, fields, constants Multipart names Multi-part & arity names Blocks for control Blocks for control Non-local returns Non-local returns Optionally typed Optionally & gradually typed Modules as classes Modules as objects Classes inside classes 
 Classes inside classes Objects inside methods 15

  16. NS 16

  17. Are We Fast Yet? Java Node.js (V8) Moth Higgs 0.75 1.00 2.00 3.00 4.00 10.00 50.00 Run-time factor, normalized to Java 17

  18. def o = object { 
 method three {3} 
 } 18

  19. def o = object { 
 method three {3} 
 } 
 o.three 
 19

  20. def o = object { 
 method three {3} 
 } 
 type Three = interface { three } 20

  21. def o = object { 
 method three {3} 
 } 
 type Three = interface { three } def p : Three = o p.three 21

  22. def o = object { 
 method three {3} 
 } 
 type Three = interface { three } method wantsThree( trois : Three ) { } wantsThree( o ) 22

  23. def o = object { 
 method four {3} 
 } 
 type Three = interface { three } method wantsThree( trois : Three ) { } wantsThree( o ) // should crash! 23

  24. Transient Typechecks method wantsThree( trois : Three ) { } method wantsThree( trois ) { 
 assert { Three.match(trois) } 
 } 24

  25. Bounce Transient Overhead CD DeltaBlue Fannkuch Float Go GraphSearch Havlak Json List Mandelbrot NBody Permute PyStone Queens Richards Sieve Snake SpectralNorm Storage Towers 0.8 0.9 1.0 1.1 1.5 2.0 25 Run-time factor, normalized to Moth (untyped)

  26. Warmup Bounce CD DeltaBlue 2.0 1.5 1.0 0.5 0.0 Fannkuch Float Go 2.0 Run-time factor, normalized to untyped (lower is better) 1.5 1.0 0.5 0.0 GraphSearch Havlak Json 2.0 1.5 1.0 0.5 0.0 List Mandelbrot NBody 2.0 1.5 1.0 0.5 0.0 Permute PyStone Queens 2.0 1.5 1.0 0.5 0.0 Richards Sieve Snake 2.0 1.5 1.0 0.5 0.0 SpectralNorm Storage Towers 2.0 1.5 1.0 0.5 0.0 0 25 50 75 100 0 25 50 75 100 0 25 50 75 100 Iterations in same VM 26

  27. Subtype Cache Defined Type Three A B … (names indicate origin) Observed Shape o1 T xa T xb T … method wantsThree( trois : Three ) { } wantsThree( o ) 27

  28. Subtype Cache 1 global record: Matrix 2 3 class TypeCheckNode(Node): 4 5 expected: Type 6 20 7 @Spec(static_guard=expected.check(obj)) 21 @Fallback 22 def check(obj: Any): 23 T = obj.get_type() 24 25 if record[T, expected] is unknown: 26 record[T, expected] = T.is_subtype_of(expected) 27 28 if not record[T, expected]: 29 raise TypeError(f"{obj} doesn � t implement {expected}") 28

  29. Specialization call wantsThree check arg trois expect read type(o) o exception ... method wantsThree( trois : Three ) { } wantsThree( o ) 29 After Würthinger et al, One VM to Rule them all Onward! 2013 


  30. call Specialization wantsThree call wantsThree check 
 cache read type Three o shape ... method wantsThree( trois : Three ) { } wantsThree( o ) 30 After Würthinger et al, One VM to Rule them all Onward! 2013 


  31. call Specialization wantsThree call wantsThree check 
 cache read o shape type Three ... method wantsThree( trois : Three ) { } wantsThree( o ) 31 After Würthinger et al, One VM to Rule them all Onward! 2013 


  32. Specialization 6 7 @Spec(static_guard= � expected.check(obj) � ) 8 def check(obj: Number): 9 pass 10 11 @Spec(static_guard= � expected.check(obj) � ) 12 def check(obj: String): 13 pass 14 15 ... 16 17 @Spec(guard= � obj.shape==cached_shape � , static_guard= � expected.check(obj) � ) 18 def check(obj: Object, @Cached(obj.shape) cached_shape: Shape): 19 pass 20 21 @Fallback 22 def check(obj: Any): 23 T = obj.get_type() 24 25 if record[T, expected] is unknown: 32

  33. Optimizations Moth (untyped) Moth (both) Moth (optimized node) Moth (subtype cache) Moth (neither) 0.85 1.00 2.00 8.00 30.00 50.00 100.00 150.00 Run-time factor, normalized to Moth (untyped) 33

  34. Optimizations Type Test Enabled Optimization mean #invocations min max check_generic Neither 137,525,845 11,628,068 896,604,537 Subtype Cache 137,525,845 11,628,068 896,604,537 Optimized Node 292 68 1,012 Both 292 68 1,012 is_subtype_of Neither 134,125,215 11,628,067 896,604,534 Subtype Cache 16 10 29 Optimized Node 292 68 1,012 Both 16 10 29 34

  35. Pathology 1 var elem: ListElement := headOfList 2 while (...) do { 79% 3 elem := elem.next 4 } 35

  36. Local Semantics def o = object { 
 method three -> Unknown {3} 
 } type ThreeString = interface { three -> String } def t : ThreeString = o printString (t.three) 36

  37. Lexical Semantics def o = object { 
 method three -> Unknown {3} 
 } type ThreeString = interface { three -> String } def t : ThreeString = o printString (t.three) 37

  38. Shallow Semantics def o = object { 
 method three -> Number {3} 
 } type ThreeString = interface { three -> String } method wantsThree( trois : ThreeString ) {} 
 wantsThree( o ) 38

  39. Deep Semantics def o = object { 
 method three -> Number {3} 
 } type ThreeString = interface { three -> String } method wantsThree( trois : ThreeString ) {} 
 wantsThree( o ) 39

  40. Deep emulates Shallow def o = object { 
 method three -> Number {3} 
 } type Three = interface { three -> Unknown } method wantsThree( trois : Three ) {} 
 wantsThree( o ) 40

  41. Concrete Semantics def o = object { 
 method three -> Unknown {3} 
 } type ThreeString = interface { three -> String } method wantsThree( trois : ThreeString ) {} 
 wantsThree( o ) 41

  42. Graceful Semantics? def o = object { 
 method three -> Unknown {3} 
 } type ThreeString = interface { three -> String } method wantsThree( trois : ThreeString ) {} 
 wantsThree( o ) 42

  43. Pathology for (1 .. innerIterations) do { i: Number -> 
 system.advance(0.01) 
 } 1. asInteger.to (innerIterations) do { i: Number -> 
 system.advance(0.01) 
 } 43

  44. Dialects SomeDialect DialectDialect ModuleC SomeDialect dialect dialect "SomeDialect" "DialectDialect" method ... diaMeth { ... diaMeth } ... 44

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend