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

Benchmarkuj z głową

Benchmarkuj z głową

Radosław Bułat

January 19, 2016
Tweet

Transcript

  1. Disclaimer Wszystkie testy zostały przeprowadzone na komputerze Macbook Pro z

    systemem OS X El Capitan, wyposażonym w procesor Intel Core i5 2,6 Ghz, 8GB Ram i dysk SSD. Programy, jeśli nie wyspecyfikowano inaczej, były odpalane przy użyciu interpretera rubiego MRI w wersji 2.3.0p0 (64bit).
  2. Zwykle miarą jest czas, ale może to być także np.

    zużycie pamięci, ilości operacji I/O itp.
  3. Czy to jest dobra metoda? $ t i m e

    r u b y m y _ s c r i p t . r b
  4. Tak, jeśli mierzymy faktycznie wykonanie całego skryptu (bootstrap VM, ładowanie

    gemów itp.). Zwykle mierzymy jednak tylko wycinek kodu, więc ta metoda się nie sprawdza.
  5. Manualnie s t a r t = T i m

    e . n o w N = 1 0 0 _ 0 0 0 N . t i m e s { " f o o - b a r - b a z " . g s u b ( / - / , " . " ) } s t o p = T i m e . n o w p u t s " S t r i n g # g s u b : # { s t o p - s t a r t } s " S t r i n g # g s u b : 0 . 2 2 3 0 8 7 s
  6. biblioteka benchmark (stdlib) r e q u i r e

    " b e n c h m a r k " N = 1 0 0 _ 0 0 0 B e n c h m a r k . b m d o | x | x . r e p o r t ( " S t r i n g # g s u b " ) d o N . t i m e s { " f o o - b a r - b a z " . g s u b ( / - / , " . " ) } e n d x . r e p o r t ( " S t r i n g # t r " ) d o N . t i m e s { " f o o - b a r - b a z " . t r ( " - " , " . " ) } e n d e n d
  7. u s e r s y s t e m

    t o t a l r e a l S t r i n g # g s u b 0 . 2 2 0 0 0 0 0 . 0 0 0 0 0 0 0 . 2 2 0 0 0 0 ( 0 . 2 1 8 2 4 2 ) S t r i n g # t r 0 . 0 3 0 0 0 0 0 . 0 0 0 0 0 0 0 . 0 3 0 0 0 0 ( 0 . 0 3 1 7 2 9 )
  8. gem benchmark-ips r e q u i r e "

    b e n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " S t r i n g # g s u b " ) d o " f o o - b a r - b a z " . g s u b ( / - / , " . " ) e n d x . r e p o r t ( " S t r i n g # t r " ) d o " f o o - b a r - b a z " . t r ( " - " , " . " ) e n d x . c o m p a r e ! e n d
  9. C a l c u l a t i n

    g - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - S t r i n g # g s u b 3 3 . 1 5 9 k i / 1 0 0 m s S t r i n g # t r 1 0 3 . 8 1 8 k i / 1 0 0 m s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - S t r i n g # g s u b 4 3 6 . 8 0 3 k ( ± 6 . 5 % ) i / s - 2 . 1 8 8 M S t r i n g # t r 2 . 7 3 2 M ( ± 7 . 5 % ) i / s - 1 3 . 6 0 0 M C o m p a r i s o n : S t r i n g # t r : 2 7 3 1 6 5 6 . 6 i / s S t r i n g # g s u b : 4 3 6 8 0 2 . 9 i / s - 6 . 2 5 x s l o w e r
  10. r e q u i r e " b e

    n c h m a r k / i p s " N = A R G V [ 0 ] . t o _ i a r r = ( 1 . . N ) . t o _ a B e n c h m a r k . i p s d o | x | x . r e p o r t ( " A r r a y # i n c l u d e ? " ) d o a r r . i n c l u d e ? ( r a n d ( a r r . s i z e ) ) e n d x . r e p o r t ( " A r r a y # b s e a r c h " ) d o v = r a n d ( a r r . s i z e ) a r r . b s e a r c h { | e | e > = v } e n d x . c o m p a r e ! e n d
  11. $ ruby include-vs-bsearch.rb 10_000 A r r a y #

    b s e a r c h : 9 5 7 9 5 9 . 3 i / s A r r a y # i n c l u d e ? : 3 3 2 7 1 . 6 i / s - 2 8 . 7 9 x s l o w e r $ ruby include-vs-bsearch.rb 1_000 A r r a y # b s e a r c h : 1 1 6 5 8 4 7 . 6 i / s A r r a y # i n c l u d e ? : 2 9 9 4 4 4 . 3 i / s - 3 . 8 9 x s l o w e r
  12. gem benchmark-bigo r e q u i r e "

    b e n c h m a r k / b i g o " B e n c h m a r k . b i g o d o | x | x . m i n _ s i z e = 0 x . g e n e r a t o r { | s i z e | ( 1 . . s i z e ) . t o _ a } x . r e p o r t ( " A r r a y # i n c l u d e ? " ) d o | a r r , s i z e | a r r . i n c l u d e ? ( r a n d ( s i z e ) ) e n d x . r e p o r t ( " A r r a y # b s e a r c h " ) d o | a r r , s i z e | v = r a n d ( s i z e ) a r r . b s e a r c h { | e | e > = v } e n d x . c h a r t ! e n d
  13. $ ruby include-vs-bsearch.rb 50 A r r a y #

    i n c l u d e ? : 2 4 4 3 8 5 6 . 0 i / s A r r a y # b s e a r c h : 1 6 2 7 2 4 1 . 2 i / s - 1 . 5 0 x s l o w e r $ ruby include-vs-bsearch.rb 150 A r r a y # b s e a r c h : 1 3 9 5 9 8 8 . 6 i / s A r r a y # i n c l u d e ? : 1 3 8 9 8 8 0 . 7 i / s - 1 . 0 0 x s l o w e r
  14. Dlaczego? a r r . i n c l u

    d e ? ( v ) Przekazuje sterowanie do implementacji w C. Metoda Fixnum#== nie jest wywoływana, chyba, że zostanie nadpisana. a r r . b s e a r c h { | e | e > = v } Przekazuje sterowanie do implementacji w C, ale każde porównanie to koszt wywołania i wykonania bloku, który jest zaimplementowany w czystym Rubym.
  15. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " F i x n u m # + " ) { 2 + 3 } x . r e p o r t ( " F i x n u m # * " ) { 2 * 3 } x . c o m p a r e ! e n d
  16. F i x n u m # + : 1

    0 7 0 1 9 7 8 . 3 i / s F i x n u m # * : 9 6 5 0 9 6 8 . 6 i / s - 1 . 1 1 x s l o w e r
  17. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " F i x n u m # + " ) { 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; 2 + 3 ; } x . r e p o r t ( " F i x n u m # * " ) { 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; 2 * 3 ; } x . c o m p a r e ! e n d
  18. F i x n u m # + : 5

    4 8 1 4 7 3 . 1 i / s F i x n u m # * : 3 9 3 8 8 5 7 . 4 i / s - 1 . 3 9 x s l o w e r
  19. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " e m p t y b l o c k " ) { } x . r e p o r t ( " F i x n u m # + " ) { 2 + 3 } x . r e p o r t ( " F i x n u m # * " ) { 2 * 3 } x . c o m p a r e ! e n d
  20. e m p t y b l o c k

    : 1 1 8 4 4 4 9 2 . 5 i / s F i x n u m # + : 1 1 0 7 6 5 9 7 . 5 i / s - 1 . 0 7 x s l o w e r F i x n u m # * : 9 8 1 2 8 0 7 . 9 i / s - 1 . 2 1 x s l o w e r
  21. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " F i x n u m # + " , " 2 + 3 ; " * 1 0 _ 0 0 0 ) x . r e p o r t ( " F i x n u m # * " , " 2 * 3 ; " * 1 0 _ 0 0 0 ) x . c o m p a r e ! e n d
  22. F i x n u m # + : 9

    5 3 8 . 4 i / s F i x n u m # * : 6 0 9 9 . 6 i / s - 1 . 5 6 x s l o w e r
  23. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " d o w n c a s e " , ' " F O O B A R " . d o w n c a s e ; ' * 1 _ 0 0 0 ) x . r e p o r t ( " d o w n c a s e ! " , ' " F O O B A R " . d o w n c a s e ! ; ' * 1 _ 0 0 0 ) x . c o m p a r e ! e n d
  24. d o w n c a s e ! :

    1 6 3 5 7 . 6 i / s d o w n c a s e : 1 1 0 3 4 . 8 i / s - 1 . 4 8 x s l o w e r
  25. r e q u i r e " b e

    n c h m a r k / i p s " B e n c h m a r k . i p s d o | x | x . r e p o r t ( " g s u b " , ' " f o o b a r b a z " . g s u b ( / . / , " z " ) ; ' * 1 0 _ 0 0 0 ) x . r e p o r t ( " g s u b ! " , ' " f o o b a r b a z " . g s u b ! ( / . / , " z " ) ; ' * 1 0 _ 0 0 0 ) x . c o m p a r e ! e n d
  26. g s u b ! : 2 8 . 9

    i / s g s u b : 2 8 . 9 i / s - 1 . 0 0 x s l o w e r
  27. r e q u i r e " o b

    j s p a c e " G C . d i s a b l e d e f m e m o r y _ u s a g e ` p s - o r s s = - p # { P r o c e s s . p i d } ` . t o _ i / 1 0 2 4 e n d b e f o r e = m e m o r y _ u s a g e 1 _ 0 0 0 _ 0 0 0 . t i m e s { " f o o - b a r - b a z " . g s u b ( / - / , " . " ) } a f t e r = m e m o r y _ u s a g e p u t s " A l l o c a t e d m e m o r y : # { a f t e r - b e f o r e } M B " p u t s " A l l o c a t e d s t r i n g s : # { O b j e c t S p a c e . c o u n t _ o b j e c t s [ : T _ S T R I N G ] } "
  28. A l l o c a t e d m

    e m o r y : 6 9 6 M B A l l o c a t e d s t r i n g s : 5 0 1 0 1 4 7
  29. r e q u i r e " o b

    j s p a c e " G C . d i s a b l e d e f m e m o r y _ u s a g e ` p s - o r s s = - p # { P r o c e s s . p i d } ` . t o _ i / 1 0 2 4 e n d b e f o r e = m e m o r y _ u s a g e 1 _ 0 0 0 _ 0 0 0 . t i m e s { " f o o - b a r - b a z " . g s u b ! ( / - / , " . " ) } a f t e r = m e m o r y _ u s a g e p u t s " A l l o c a t e d m e m o r y : # { a f t e r - b e f o r e } M B " p u t s " A l l o c a t e d s t r i n g s : # { O b j e c t S p a c e . c o u n t _ o b j e c t s [ : T _ S T R I N G ] } "
  30. A l l o c a t e d m

    e m o r y : 6 9 5 M B A l l o c a t e d s t r i n g s : 5 0 1 0 1 4 7
  31. r e q u i r e ' b e

    n c h m a r k / i p s ' d e f p a r a l l e l a , b , c , d , e , f , g , h = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 e n d d e f s e q u e n t i a l a = 1 b = 2 c = 3 d = 4 e = 5 f = 6 g = 7 h = 8 e n d B e n c h m a r k . i p s d o | x | x . r e p o r t ( ' P a r a l l e l ' ) { p a r a l l e l } x . r e p o r t ( ' S e q u e n t i a l ' ) { s e q u e n t i a l } x . c o m p a r e ! e n d
  32. S e q u e n t i a l

    : 6 2 5 7 6 4 6 . 4 i / s P a r a l l e l : 2 7 7 0 6 8 8 . 2 i / s - 2 . 2 6 x s l o w e r
  33. Ktoś inny zauważył, że przypisanie równoległe ma dodatkowy koszt utworzenia

    nowej tablicy, ale tylko gdy jest wykonywane jako ostatnia instrukcja w metodzie.
  34. p r y ( m a i n ) >

    p a r a l l e l = > [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] p r y ( m a i n ) > s e q u e n t i a l = > 8
  35. r e q u i r e ' b e

    n c h m a r k / i p s ' d e f p a r a l l e l a , b , c , d , e , f , g , h = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 n i l e n d d e f s e q u e n t i a l a = 1 b = 2 c = 3 d = 4 e = 5 f = 6 g = 7 h = 8 n i l e n d B e n c h m a r k . i p s d o | x | x . r e p o r t ( ' P a r a l l e l ' ) { p a r a l l e l } x . r e p o r t ( ' S e q u e n t i a l ' ) { s e q u e n t i a l } x . c o m p a r e ! e n d
  36. P a r a l l e l : 7

    3 1 7 2 6 6 . 9 i / s S e q u e n t i a l : 6 1 4 9 9 5 5 . 8 i / s - 1 . 1 9 x s l o w e r
  37. r e q u i r e ' b e

    n c h m a r k / i p s ' B e n c h m a r k . i p s d o | x | x . r e p o r t ( ' P a r a l l e l ' , ' a , b , c , d , e , f , g , h = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ; ' * 1 0 _ 0 0 0 ) x . r e p o r t ( ' S e q u e n t i a l ' , ' a = 1 ; b = 2 ; c = 3 ; d = 4 ; e = 5 ; f = 6 ; g = 7 ; h = 8 ; ' * 1 0 _ 0 0 0 ) x . c o m p a r e ! e n d
  38. S e q u e n t i a l

    : 3 0 3 1 . 0 i / s P a r a l l e l : 3 0 2 9 . 8 i / s - 1 . 0 0 x s l o w e r
  39. ; ?

  40. r e q u i r e ' b e

    n c h m a r k / i p s ' d e f p a r a l l e l a , b , c , d , e , f , g , h = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 n i l e n d d e f s e q u e n t i a l a = 1 ; b = 2 ; c = 3 ; d = 4 ; e = 5 ; f = 6 ; g = 7 ; h = 8 ; n i l e n d B e n c h m a r k . i p s d o | x | x . r e p o r t ( ' P a r a l l e l ' ) { p a r a l l e l } x . r e p o r t ( ' S e q u e n t i a l ' ) { s e q u e n t i a l } x . c o m p a r e ! e n d
  41. P a r a l l e l : 7

    2 9 1 1 2 9 . 5 i / s S e q u e n t i a l : 6 2 0 3 3 9 0 . 0 i / s - 1 . 1 8 x s l o w e r
  42. r e q u i r e ' b e

    n c h m a r k / i p s ' d e f p a r a l l e l a , b , c , d , e , f , g , h = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 n i l e n d d e f s e q u e n t i a l a = 1 ; b = 2 ; c = 3 ; d = 4 ; e = 5 ; f = 6 ; g = 7 ; h = 8 ; n i l e n d B e n c h m a r k . i p s d o | x | x . r e p o r t ( ' P a r a l l e l ' ) { p a r a l l e l } x . r e p o r t ( ' S e q u e n t i a l ' ) { s e q u e n t i a l } x . c o m p a r e ! e n d
  43. P a r a l l e l : 7

    2 4 7 1 0 7 . 0 i / s S e q u e n t i a l : 7 2 2 7 8 9 7 . 0 i / s - 1 . 0 0 x s l o w e r
  44. p u t s R u b y V M

    : : I n s t r u c t i o n S e q u e n c e . c o m p i l e ( " a = 1 ; b = 2 ; " ) . d i s a s m
  45. 0 0 0 0 t r a c e 1

    0 0 0 2 p u t o b j e c t _ O P _ I N T 2 F I X _ O _ 1 _ C _ 0 0 0 3 s e t l o c a l _ O P _ _ W C _ _ 0 3 0 0 0 5 p u t o b j e c t 2 0 0 0 7 d u p 0 0 0 8 s e t l o c a l _ O P _ _ W C _ _ 0 2 0 0 1 0 l e a v e
  46. p u t s R u b y V M

    : : I n s t r u c t i o n S e q u e n c e . c o m p i l e ( " a = 1 ; \ n b = 2 ; " ) . d i s a s m
  47. 0 0 0 0 t r a c e 1

    0 0 0 2 p u t o b j e c t _ O P _ I N T 2 F I X _ O _ 1 _ C _ 0 0 0 3 s e t l o c a l _ O P _ _ W C _ _ 0 3 0 0 0 5 t r a c e 1 0 0 0 7 p u t o b j e c t 2 0 0 0 9 d u p 0 0 1 0 s e t l o c a l _ O P _ _ W C _ _ 0 2 0 0 1 2 l e a v e
  48. diff t r a c e 1 p u t

    o b j e c t _ O P _ I N T 2 F I X _ O _ 1 _ C _ s e t l o c a l _ O P _ _ W C _ _ 0 3 + t r a c e 1 p u t o b j e c t 2 d u p s e t l o c a l _ O P _ _ W C _ _ 0 2 l e a v e
  49. d e f f o o a , b =

    1 , 2 e n d d e f b a r a = 1 b = 2 e n d T r a c e P o i n t . n e w ( : l i n e ) d o | t p | p [ t p . e v e n t , t p . l i n e n o ] e n d . e n a b l e f o o b a r [ : l i n e , 1 4 ] [ : l i n e , 2 ] [ : l i n e , 1 5 ] [ : l i n e , 6 ] [ : l i n e , 7 ]
  50. disable_trace.rb R u b y V M : : I

    n s t r u c t i o n S e q u e n c e . c o m p i l e _ o p t i o n = { t r a c e _ i n s t r u c t i o n : f a l s e }
  51. $ ruby assignment.rb P a r a l l e

    l : 7 2 9 5 1 5 8 . 6 i / s S e q u e n t i a l : 6 2 8 5 2 7 7 . 7 i / s - 1 . 1 6 x s l o w e r $ ruby -r./disable_trace assignment.rb S e q u e n t i a l : 7 9 1 5 2 1 3 . 2 i / s P a r a l l e l : 7 8 9 6 6 9 7 . 9 i / s - 1 . 0 0 x s l o w e r