Download - MmapScanner
![Page 1: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/1.jpg)
MmapScannerとみたまさひろ2011-07-18
![Page 2: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/2.jpg)
自己紹介id:tmtms
@tmtms
日本MySQLユーザ会
長野ソフトウェア技術者グループ(NSEG)
![Page 3: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/3.jpg)
重要「MySQL徹底入門第三版」近日発売
画像は第二版
![Page 4: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/4.jpg)
Rubyたぶん13年くらい
バージョン 1.1 から
「Rubyをイヤイヤ使わされてる人」を作る仕事
SIerのRubyistの悲しき紋章
![Page 5: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/5.jpg)
趣味誰も使わないライブラリを作る
自分でも使わない
![Page 6: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/6.jpg)
MySQL/RubyMySQL C library wrapper
割と使われてる
オワコン
![Page 7: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/7.jpg)
Ruby/MySQLpure Ruby
あまり使われてない
名前が悪い
![Page 8: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/8.jpg)
OptConfigOptionParser みたいなもの
設定ファイルから読む
自動補完する/しない
--help に出すかどうか
複数指定した時のふるまい最後を採用/配列で全部/エラー
![Page 9: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/9.jpg)
LightCsvCSVパーサー
「うわっRubyのCSV遅すぎ」
ついカッとなって作った
![Page 10: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/10.jpg)
速度
ken_all.csv(123000行, 12MB)
![Page 11: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/11.jpg)
速度
ken_all.csv(123000行, 12MB)
![Page 12: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/12.jpg)
LightCsv103行 (コメント/空行除く)
CSV のパースをするだけなのに
![Page 13: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/13.jpg)
CSVパース物理行単位で処理できない
ほげ,"改行を\r\n含むカラム",ふが
固定サイズで読むと CR と LF がわかれたり
![Page 14: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/14.jpg)
全部読んじゃえメモリ食う
![Page 15: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/15.jpg)
mmap(2)ファイルをメモリにマッピング
![Page 16: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/16.jpg)
read通常は open して少しずつ read
![Page 17: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/17.jpg)
mmapファイル全体(または一部)をメモリにマップ
![Page 18: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/18.jpg)
mmap速い
メモリを食わない
大きなファイルで有用
![Page 19: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/19.jpg)
Rubyからは使いにくいメモリを直接さわれない
Stringとして扱う時はコピーが必要
![Page 20: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/20.jpg)
MmapScannerRuby の拡張ライブラリ
StringScanner の mmap 版
mmap 領域を正規表現で走査
取り出したものも MmapScanner
![Page 21: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/21.jpg)
MmapScanner部分的に取り出しても同じメモリを共有
![Page 22: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/22.jpg)
使い方
f = File.open("filename")m = MmapScanner.new(f)word = m.scan(/[a-z0-9_]+/i)word # => MmapScannerword.to_s # => String
![Page 23: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/23.jpg)
CSVパーサー
require 'mmapscanner'class MmapCSV include Enumerable def initialize(filename) File.open(filename) do |f| @ms = MmapScanner.new(f) end end def each rec = [] until @ms.eos? if @ms.skip(/\"((?:\"\"|[^\"])*)\"(,|\r\n|\n|\z)/n) rec.push @ms.matched_str(1).gsub(/\"\"/,'"') elsif @ms.skip(/([^,\"\r\n]*)(,|\r\n|\n|\z)/n) rec.push @ms.matched_str(1) else raise "invalid format: #{@ms.rest.slice(0,20).to_s}" end unless @ms.matched_str(2) == ',' yield rec rec.clear end end endend
![Page 24: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/24.jpg)
速度
ken_all.csv(123000行, 12MB)
![Page 25: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/25.jpg)
課題1.9 only
ASCII-8BIT only
明に munmap できない
![Page 26: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/26.jpg)
FAQどうせ拡張ライブラリ作るんだったらCSVパーサーをCで書けば良かったんじゃね?
![Page 27: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/27.jpg)
目的と手段の正しい理解目的: RubyでCSVパーサーを書く
手段: 拡張ライブラリ
![Page 28: MmapScanner](https://reader034.vdocuments.pub/reader034/viewer/2022042815/557ad4c4d8b42a0b188b52cd/html5/thumbnails/28.jpg)
以上