RubyKaigi 2018 ï¼æ¥ç®ã«åå ãã¦ãã¾ããããæ¼ã«å¼å½é£ã¹ããã¨ãä»å°åè·¡ãè¦ã«æ©ãã¦è¡ã£ã¦ãã¾ããï¼å¸°ãã¯ã¿ã¯ã·ã¼ã ã£ããã©ï¼ã天æ°ãè¯ãã¦æºè¶³åº¦ãé«ãã£ãã§ãã
My way with Ruby
æ´»åããã¦ããå 容ã®ã¯ãªãã
- ããªã¼ã½ããã¦ã§ã¢ã使ã£ã¦ Ruby ã§ã§ãããã¨ãããããå¢ãã
- ã©ã¤ãã©ãªã®ã¡ã³ããã³ã¹
- 130ãããã¡ã³ããã³ã¹ãã¦ããã©ã¤ãã©ãªããã
èªåã«ã¨ã£ã¦å¿ è¦ã ã£ãããã
Web ã® feed
RSS/ATOM
- RSS/ATOM ã® validation
- Ruby 2.6 以éã¯ãã¼ã¯ã¼ãå¼æ°ã«å¯¾å¿
REXML
- REXML â Ruby Electric XML
- ã©ã¤ãã©ãªä½è 㨠Ruby ãéãã¦ããã¨ããããã¨ã«ãªã£ã
- ã³ã¼ãæ親ä¼ãã¾ãã
- Matz ãåå ãã¾ãã
- 2010å¹´ããã¡ã³ããã¼ã«ãªã£ã
- Ruby ã ãã§æ¸ããã¦ãã
- install ãç°¡å
- æªæ¥ã®è©±
- NodeSet ãªãã¸ã§ã¯ããåããAPIãã»ãã
- CSS ã»ã¬ã¯ã¿ãããã¨è¯ããã
- åªå 度ã¯é«ããªããä¸ç·ã«ãããã人ããï¼
ãã¬ã¼ã³ãã¼ã·ã§ã³
- Rabbit
- 2004å¹´ã«ãªãªã¼ã¹ãã
- 2010å¹´ãã Matz ã使ãå§ãã
- RDã®ãµãã¼ããå¿
é
- Ruby Document
- Text ãã¼ã¹ã®ãã¼ã¯ã¢ãã
- ã¹ã©ã¤ãã®å ¬é
- ãã¬ã¼ã³ãã¼ã·ã§ã³ãã¼ã«ã«å¿
è¦ãªæ©è½ â GUI
- Ruby/GTK3
- ä¸è¶³ãã¦ããæ©è½ããã£ãã追å ãã¦ãããã¬ã¼ã³ãä½ã£ã¦ãããã
- Ruby/GI
- èªåçã« binding ãç¨æãã¦ããããã®ã£ã½ã
- æã§æ¸ãããã¯ãªã¼ãã¼ããããããããé ã
- JITã§é«éåããããã
- Ruby/Poppler
- Ruby/GStreamer
- rcairo
- GC é¢ä¿ã§åé¡ããã£ã â Ruby 2.4 ã§ç´ããã
- ç°¡åãªã¤ã³ã¹ãã¼ã«
- rake-compiler
Test
- test-unit
- 2008å¹´ããã¡ã³ããã¼ã«ãªã£ã
- ã°ã«ã¼ãåã®æ©è½ã追å ãã
- ãã¼ã¿é§åãã¹ã
- éé ã®ããã¯ãã¬ã¼ã¹
- Ruby 2.5 ã®æ©è½ããtest-unit ã§ãåãæåã«ãã
- RR
å ¨ææ¤ç´¢
- Rroonga
- Rabbit ã®ãµã¤ãã¨ããã¾ãµã¼ãã§ä½¿ç¨ãã¦ãã
- I18n
- YARD
- RDoc
- jekyll
- groonga-client
- Ranguba (WIP)
ãã¼ã¿å¦ç
- CSV parser
- 2018å¹´ããã¡ã³ããã¼ã«ãªã£ã
- CSVãã©ã¼ãããã®åé¡ç¹
- ãã¼ã¹ããã®ãé£ããããã¼ã¹ãé ã
- Red Arrow
- Apache Arrowã®å ¬å¼Rubyãã¤ã³ãã£ã³ã°ã«ãªã£ã
- Ruby/GI ã使ã£ã¦ã
- Apache Arrow
- ã¹ã´ã¤éããã¼ã¿ãã©ã¼ããã
- ããããªè¨èªããµãã¼ã
- æè¿ã®ãã¼ã¿å¦ççéã§ã¯ããã大äºãª1ãã¼ã¹
- Apache Parquet
- ã¹ã´ã¤éããã¼ã¿ãã©ã¼ããã
- Red Data Tools
- Red Data Sets
- jekyll + jupyter notebook
- Red OpenCV
- Ruby/GI ã使ã£ã¦ã
- RubyData Workshop ãä»æ¥ã®å¤æ¹ã«ãããã
Faster Apps, No Memory Thrash: Get Your Memory Config Right
Appfolio ã®ã²ã¨
Tiny Objects
Symbol ã¿ãããªãã®ãExtra ãªã¡ã¢ãªé åãåããªããã®ã
Small Objects
String ã¿ãã㪠40-byte slot ãªãªãã¸ã§ã¯ããã¡ã¢ãªãã¼ã¸ãã¨ã« 408 Slots ãå²ãå½ã¦ãããã
Big Objects
Slot ã®ãµã¤ãºã«ãããªããããªå¤§ããªé åã確ä¿ãããªãã¸ã§ã¯ãã
GC
Ruby 㯠ä¸ä»£å¥ Mark/Sweep GC ãæ¡ç¨ãã¦ããã ã¨ã¦ãè¯ãããbest-in-the-world ã§ãªãã
- Major GC ã¯å ¨ã¦ã®ãªãã¸ã§ã¯ãããã§ãã¯
- Minor GC ã¯æ°ãããªãã¸ã§ã¯ãã®ã¿ããã§ãã¯
æåã§GC ãåããæ¹æ³
GC.start # major GC.start(full_mark: false) # minor
GC ã®ãã§ã¼ãº
- ãªãã¸ã§ã¯ããå¢ãã â ã´ããéãã â slots ãæ¡å¼µãã
GC ã® Mark & sweep ã¯æéãããã
- å°ããªãªãã¸ã§ã¯ãããããã使ãããã大ããªãªãã¸ã§ã¯ããï¼ã¤ä½¿ãæ¹ããã°ãã°è¯ã
- gsub! ã concat ã使ãã¨ãã´ããæ¸ã Mark & sweep ã§å¿ è¦ã ã£ã CPU 使ç¨éãã»ã¼ãã§ãã¾ãã
RUBY_GC_XXXX ã¨ããç°å¢å¤æ°ã§ GC ãå¶å¾¡ã§ããã(https://qiita.com/yuroyoro/items/14ec7079f6574ad74409 ã«æ¸ããã¦ãããããªãã®)
- ç°å¢å¤æ°ãã»ããããã°èµ·åæãã GC ã調æ´ã§ãèµ·åæéãç縮ã§ãã¾ãã
EnvMem: A Memory Tool
https://github.com/noahgibbs/env_mem
gem install env_mem
jemalloc
Ruby 㯠jemalloc ããµãã¼ããã¦ãã jemallocã使ãã¨end-to-end ã§ãã¼ã¿ã«10%-12% ãããã¹ãã¼ãã¢ããããã
ã¹ãã¼ããããããã®ã½ãªã¥ã¼ã·ã§ã³
- ã´ããå°ãªã
- ç°å¢å¤æ°
- jemalloc
- ææ°ã®Ruby
ãã©ã°ã¡ã³ãã¼ã·ã§ã³
Slot ã使ãã¨ã ãã¼ã¸å ã® 408 Slots ã解æ¾ãããã¾ã§ç§»åã§ããªã
GC::Profiler
GC ã§ä½ãèµ·ãã£ã¦ããã詳細ãç¥ãããã£ãã â GC::Profiler.enable
GC::Profiler.enable # DO something GC::Profiler.report
Guild Prototype
Guild ã®é²æã®è©±
Background of Guild
Motivation
- Productivity
- Performance by Parallel execution
- Ruby ã§ã¯ Thread ã並ååä½ããªã
- å¤ãã®äººã ã¯è¤æ°ã® CPU ã³ã¢ããã«ã«ä½¿ãããã¨æãã§ã
ãã¢
- 40ã¹ã¬ããåã CPU + ubuntu 16.10
- fib(23) x 100_000 å
- Guild ã使ãã¨13åã§çµãã£ã
- ã·ã³ã°ã«ã¹ã¬ããã 㨠3.5æé
- fib(9)ããããã Guild ã®ã»ããã¹ãã¼ãã¢ãããå§ãã
ruby/test/**/*
ã®ã¯ã¼ããã«ã¦ã³ããã- ã·ã³ã°ã«ã ã¨1.73 sec
- 40 Guilds ã 㨠6.13 sec ã§ã·ã³ã°ã«ããé ããªã£ã
- é ããªã£ãã®ã¯ GC ã®ããããã
ä»æ§
- non-sharable
- mutable object (Array, String...) ã Guild éã§å ±æã§ããªã
sharable
- immutable objects 㯠Guild éã§å ±æã§ãã
- Class/Module objects
- Special mutable objects
- Isolated Proc
Guildéã®éä¿¡ API
- Actor model
- shareable object ãéä¿¡ãã
- non-shareble object ã移åãã
Guild ã®å®è£
- Before
- VM â Threads â Fibers
- After
- VM â Guilds â Threads â Fibers
- ãã¤ãã£ããªã¹ã¬ããã並ååä½ããããã«ãªã
GC ã®å¦çãèµ°ãã¨ããã®éãå ¨ã¦ã®Guilds ãæ¢ã¾ã
ãããããããã¨
- æ©è½
- Prohibit
- åæ
- Shareable ãããã³ã«
- æé©å
Guild ã®ååã«ã¤ãã¦
ãã¬ãã£ãã¯ã¹ã P (Process), T (Thread), F (Fiber) ããé¿ãã
åé¡ç¹
"Move" ãªãã¬ã¼ã·ã§ã³ãä¸è¬çãããªã
mruby can be more lightweight
ãªã mruby ãå°ãããªãã¨é§ç®ã
ãããããè¨äºã«è¼ã£ã¦ãããã¼ãã 96K ãã RAM ããªã
ã©ãããã
ã³ã³ã»ãã
- define 㧠mruby ã®æ©è½ãç¡å¹ã«ããRAM ã®ä½¿ç¨éãæ¸ãã
- å®è£ ããã㦠ROM ã«ç½®ã㦠RAM ã空ãã
çµæ
- default ã 㨠153 KB ã®RAMã使ã
- æ©è½ãç¡å¹ã«ãã¦ãã㨠83 KB
- ROM ã«è¼ã㦠67 KB
ã©ããã£ãã
- å®è¡æã«æ±ºã¾ã£ã¦ããã¡ã½ãããSymbolã ROM ã«é ç½®ãã
- å®è¡ä¸ã«è¿½å ãããã¡ã½ãããSymbol㯠RAM ã«ç½®ã
- RAM ä¸ã®ã¡ã½ãããæ¢ç´¢ãããªããã° ROM ããæ¢ãããã«ãã
- Hash ã®ããã©ã«ãã®ãã¼ãã«ãµã¤ãºãç¡çç¢çå°ãããã
åé¡ç¹
remove_method
㧠ROM ã«é
ç½®ãããã¡ã½ãããåé¤ã§ããªã
ææ
ã¬ãã§çµã¿è¾¼ã¿ã·ã¹ãã ãªè©±ã ã£ããæããããæ¥æ ã«ããã®ã§æãããã£ããã»ã»ã»ã
Ruby Programming with Type Checking
Steep
- Gradual typing for Ruby
- ã³ã¡ã³ãã¨ãã¦ã®åã¢ããã¼ã·ã§ã³
- ããã°ã©ãã¼ã«ããåå®ç¾©
- ãã¼ã«ã«ã®åæ¨è«
version 0.3.0ãæ¨æ¥ãªãªã¼ã¹ãã
Sorbet ã¨ã®æ¯è¼
ãã¢
ãã¢ã®ã³ã¼ã
1 + "2"
ã³ãã³ã
$ steep check
以ä¸ã®ãããªåãå®ç¾©ãããã¡ã¤ã«ãå¥éç¨æã§ããã
class Presentation @title: String @speaker: Speaker def initialize: (title: String, speaker: Speaker) -> any def print: (?_Puts) -> void def title: -> String def speaker: -> Speaker end
åãã§ãã¯ã®ã¹ããã
- ã·ã°ããã£ã¼ãæ¸ã
- Ruby ã³ã¼ããã¢ããã¼ã·ã§ã³ãä»ãã¦æ¸ã
- steep check
1.
ã¸æ»ã
ãã¢
strictãªãã§ãã¯ããããå ´åã«ã¯ steep check --strict
ã¨ãã
steep scaffold
ã§åå®ç¾©ãèªåçæã§ãã
åå®ç¾©ã® 40 % ã¯ã©ã¤ãã©ãªã®ããã ã£ãããã gem ãåå®ç¾©ä»ãã§ãªãªã¼ã¹ãããã°ããããåæ¸ã§ããã
ã¡ã¿ããã°ã©ãã³ã°
- Rails ã¿ããã«ã¡ã¿ããã°ã©ãã³ã°ä½¿ãã¾ãã£ã¦ããã¨ããã®åãã§ãã¯ã¯å¤§å¤ãã
- ã¨ãããããä»ã®ã¨ãã ActionArg 使ã£ã¦ãã ããã¨ã®ãã¨
RNode with code locations
- ã¢ã¤ã³ã³ã¯ç«ã§ã¯ãªãããã¯ãã¦ã§ãã
- æ¥é±ãããã¬ã¸ã£ã¼ãã¼ã¿ã«joinãã¾ãã¨ã®ãã¨ã
2.5 㧠RNode ãå¤ããã³ã¼ãã¬ã³ã¸ãå¢ãã¦ããã 以ä¸ã®ã±ã¼ã¹ã§ä¾¿å©ã ãã追å
- ä¾å¤
- warning
- ãã¹ãã®ã«ãã¬ãã¸
ã«ã©ã ã¨ã¯ã
- 2.4 ã¾ã§ã¯è¡çªå·ããä¿æãã¦ããªãã£ã
- 2.5 ããã«ã©ã æ
å ±ã追å ãã
- è¡ã®å é ããã©ããããé¢ãã¦ãããã¨ããæ å ±
- Byte length
(1,0)
ã¿ãããªè¡¨ç¾ã(è¡, ã«ã©ã )
ãªãå¿ è¦ã«ãªã£ãã
2.5 ã§è¿½å ããããã©ã³ãã«ãã¬ãã¸ã¨ã¡ã½ããã«ãã¬ãã¸ã§å¿ è¦ã«ãªã£ã
- ãã©ã³ãã«ãã¬ã㸠â åå²ã®çæ¹ãã©ãã ãå®è¡ãããã
- ã¡ã½ããã«ãã¬ãã¸
å¯è¦åããéã«ã«ã©ã æ å ±ãå¿ è¦ã ã£ãã
- 3é æ¼ç®åã«ããã²ã¨ã¤ã®è¡ã¯è¤æ°ã®åå²ãæ¸ããã¨ãã§ãã
- è¡çªå·ããç¡ãã¨ãã©ããå®è¡ããããå¤å¥ã§ããªããã
Ruby ã¹ã¯ãªããã® Tokenize
$ ruby --dump=y -e '1 + 2' | grep Shifting Shifting token tINTEGER (1.0-1.1: ) Shifting token '+' (1.2-1.3: ) Shifting token tINTEGER (1.4-1.5: ) Shifting token '\n' (1.5-1.5: ) Shifting token "end-of-input" (1.5-1.5: )
Parsing
$ ruby --dump=y -e '1 + 2'
Build AST
$ ruby --dump=p -e '1 + 2' ########################################################### ## Do NOT use this node dump for any purpose other than ## ## debug and research. Compatibility is not guaranteed. ## ########################################################### # @ NODE_SCOPE (line: 1, code_range: (1,0)-(1,5)) # +- nd_tbl: (empty) # +- nd_args: # | (null node) # +- nd_body: # @ NODE_PRELUDE (line: 1, code_range: (1,0)-(1,5)) # +- nd_head: # | (null node) # +- nd_body: # | @ NODE_OPCALL (line: 1, code_range: (1,0)-(1,5)) # | +- nd_mid: :+ # | +- nd_recv: # | | @ NODE_LIT (line: 1, code_range: (1,0)-(1,1)) # | | +- nd_lit: 1 # | +- nd_args: # | @ NODE_ARRAY (line: 1, code_range: (1,4)-(1,5)) # | +- nd_alen: 1 # | +- nd_head: # | | @ NODE_LIT (line: 1, code_range: (1,4)-(1,5)) # | | +- nd_lit: 2 # | +- nd_next: # | (null node) # +- nd_compile_option: # +- coverage_enabled: false
Compile
$ ruby --dump=i -e '1 + 2' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,5)>============================== 0000 putobject_OP_INT2FIX_O_1_C_ ( 1)[Li] 0001 putobject 2 0003 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache> 0006 leave
å®è£ ã®è©±
ãã¼ã¯ã³ä½ã£ãã¨ãã«ã©ã æ å ±ãä¿æããISeq ã¾ã§é ã«æ¸¡ããããªå¤æ´ãå°éã«ããããããåæ¥ã§ãã
å¿ç¨ä¾
- Proc ã®ã³ã¼ããã±ã¼ã·ã§ã³ãåå¾ããã¡ã½ãããä½ãã
- NoMethodError ã®ã¡ãã»ã¼ã¸ããã詳細ã«ã§ãã
- AST ãªãã¸ã§ã¯ããåããã¨ãã§ãã â Ruby 2.6 preview 2 ã«å ¥ãã¾ãã
Type Profiler: An analysis to guess type signatures
Ruby 2.6 ããã«ã¨ã³ãã¬ã¹Range (1..) ãå®è£ ãã
ary[1..] (1..).each { ...} ary.zip(1..) { |x,i| ...}
æ¢åã®ææ¡ããã¦ããåã·ã¹ãã ã«ã¤ãã¦
以ä¸ã®æ¢åã®åã·ã¹ãã ãæ¤è¨¼ãã
- Steep
- RDL
- contracts.ruby
- dry-types
- RubyTypeInference (by JetBrains)
- Sorbet (by Stripe)
RDL
- ã¢ã«ãããã¯ãªä¸çã§ã¯è¶ æå
- gem ããã
- åã¢ããã¼ã·ã§ã³ãã³ã¼ãã¨ãã¦æ¸ãå¿ è¦ããããã
æ¤è¨¼çµæã¨ãã¦ãSteep ã¿ããã«åæ å ±ã Ruby ã¨ã¯å¥ã®ãã¡ã¤ã«ã«æ¸ãã®ã Ruby 3 ã®è¦æ±ä»æ§ã£ã½ãæãã¨åãæ¢ãã¦ãã
Steep
éçãªåæ¤æ»ãä»æ¥ãçºè¡¨ããã£ãã®ã§ã¹ããã
contracts
RDL ã¿ããã«åã¢ããã¼ã·ã§ã³ãã³ã¼ãã¨ãã¦æ¸ã
RubyTypeInference
TracePoint ãé§ä½¿ãã¦ãã¹ãã³ã¼ãããåçã«åæ å ±ãæ½åºãã¦ãããã
ããã¾ã§ã®ã¾ã¨ã
Steep ããã¾ã®ã¨ããä¸çªå¥½å°è±¡
Type Profile
ä»å¾æ´åãã¦ãããããããªãã®ã®è©±ã
- åæ å ±ãæ¨å®ãããã®
- å¤å°ééã£ã¦ãã¦ãã¦ã¼ã¶ãç´ãã¦ããããããªããããã®ãæ³å®
- ããããå®é¨ã»æ¤è¨¼ãã¾ã å¿ è¦ã¨ã®ãã¨