mmapscanner

28
MmapScanner とみたまさひろ 2011-07-18

Upload: masahiro-tomita

Post on 12-Jun-2015

3.137 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: MmapScanner

MmapScannerとみたまさひろ2011-07-18

Page 2: MmapScanner

自己紹介id:tmtms

@tmtms

日本MySQLユーザ会

長野ソフトウェア技術者グループ(NSEG)

Page 3: MmapScanner

重要「MySQL徹底入門第三版」近日発売

画像は第二版

Page 4: MmapScanner

Rubyたぶん13年くらい

バージョン 1.1 から

「Rubyをイヤイヤ使わされてる人」を作る仕事

SIerのRubyistの悲しき紋章

Page 5: MmapScanner

趣味誰も使わないライブラリを作る

自分でも使わない

Page 6: MmapScanner

MySQL/RubyMySQL C library wrapper

割と使われてる

オワコン

Page 7: MmapScanner

Ruby/MySQLpure Ruby

あまり使われてない

名前が悪い

Page 8: MmapScanner

OptConfigOptionParser みたいなもの

設定ファイルから読む

自動補完する/しない

--help に出すかどうか

複数指定した時のふるまい最後を採用/配列で全部/エラー

Page 9: MmapScanner

LightCsvCSVパーサー

「うわっRubyのCSV遅すぎ」

ついカッとなって作った

Page 10: MmapScanner

速度

ken_all.csv(123000行, 12MB)

Page 11: MmapScanner

速度

ken_all.csv(123000行, 12MB)

Page 12: MmapScanner

LightCsv103行 (コメント/空行除く)

CSV のパースをするだけなのに

Page 13: MmapScanner

CSVパース物理行単位で処理できない

ほげ,"改行を\r\n含むカラム",ふが

固定サイズで読むと CR と LF がわかれたり

Page 14: MmapScanner

全部読んじゃえメモリ食う

Page 15: MmapScanner

mmap(2)ファイルをメモリにマッピング

Page 16: MmapScanner

read通常は open して少しずつ read

Page 17: MmapScanner

mmapファイル全体(または一部)をメモリにマップ

Page 18: MmapScanner

mmap速い

メモリを食わない

大きなファイルで有用

Page 19: MmapScanner

Rubyからは使いにくいメモリを直接さわれない

Stringとして扱う時はコピーが必要

Page 20: MmapScanner

MmapScannerRuby の拡張ライブラリ

StringScanner の mmap 版

mmap 領域を正規表現で走査

取り出したものも MmapScanner

Page 21: MmapScanner

MmapScanner部分的に取り出しても同じメモリを共有

Page 22: MmapScanner

使い方

f = File.open("filename")m = MmapScanner.new(f)word = m.scan(/[a-z0-9_]+/i)word # => MmapScannerword.to_s # => String

Page 23: MmapScanner

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

速度

ken_all.csv(123000行, 12MB)

Page 25: MmapScanner

課題1.9 only

ASCII-8BIT only

明に munmap できない

Page 26: MmapScanner

FAQどうせ拡張ライブラリ作るんだったらCSVパーサーをCで書けば良かったんじゃね?

Page 27: MmapScanner

目的と手段の正しい理解目的: RubyでCSVパーサーを書く

手段: 拡張ライブラリ

Page 28: MmapScanner

以上