mmapscanner

Post on 12-Jun-2015

3.137 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

自己紹介id:tmtms

@tmtms

日本MySQLユーザ会

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

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

画像は第二版

Rubyたぶん13年くらい

バージョン 1.1 から

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

SIerのRubyistの悲しき紋章

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

自分でも使わない

MySQL/RubyMySQL C library wrapper

割と使われてる

オワコン

Ruby/MySQLpure Ruby

あまり使われてない

名前が悪い

OptConfigOptionParser みたいなもの

設定ファイルから読む

自動補完する/しない

--help に出すかどうか

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

LightCsvCSVパーサー

「うわっRubyのCSV遅すぎ」

ついカッとなって作った

速度

ken_all.csv(123000行, 12MB)

速度

ken_all.csv(123000行, 12MB)

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

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

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

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

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

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

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

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

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

mmap速い

メモリを食わない

大きなファイルで有用

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

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

MmapScannerRuby の拡張ライブラリ

StringScanner の mmap 版

mmap 領域を正規表現で走査

取り出したものも MmapScanner

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

使い方

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

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

速度

ken_all.csv(123000行, 12MB)

課題1.9 only

ASCII-8BIT only

明に munmap できない

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

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

手段: 拡張ライブラリ

以上

top related