「プログラマのための文字コード技術入門」で勉強中(2)
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
- 作者: 矢野啓介
- 出版社/メーカー: 技術評論社
- 発売日: 2010/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 33人 クリック: 544回
- この商品を含むブログ (121件) を見る
- ASCII
- ISO/IEC 646 国際基準版
- JIS X 0201
- 0x5C, 0x7E
- JIS X 0208
- JIS X 2012
- 保持漢字
- Shift_JISでは扱えない
- JIS X 2013
- 第三水準、第四水準
- JIS2000, JIS2004
- JIS X 0208を包含するスーパーセット
- 漢字集合1面、漢字集合2面
- 符号化方式: Shift_JIS-2004, ISO-2022-JP-2004, EUC-JIS-2004, 国際基準版・漢字用8ビット符号
- ISO/IEC 8859
- Latin-1, ISO/IEC 8859-1
- ノーブレークスペース(NBSP), ソフトハイフン(SHY)
- Latin-2, ISO/IEC 8859-2
- Unicode, ISO/IEC 10646(UCS)
- JIS X 0221
- UCS-4, UCS-2, BMP(Basic Multilingual Plane)
- 結合文字、基底文字
- 一意な文字名
- 往復変換
- 漢字統合, CJK漢字統合, 原規格分離規則, 互換漢字
「プログラマのための文字コード技術入門」で勉強中(1)
いわゆる「文字コード」について余りにも無知なので、今更ではあるけれどちゃんと勉強しておこうと思い「プログラマのための文字コード技術入門」で入門してみた。
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
- 作者: 矢野啓介
- 出版社/メーカー: 技術評論社
- 発売日: 2010/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 33人 クリック: 544回
- この商品を含むブログ (121件) を見る
- 文字
- 符号
- 符号化
- 文字コード
- コード値
- 文字集合
- 符号化文字集合
- ASCII
- 符号位置
- 制御文字
- 図形文字
- ASCII
- ISO/IEC 646
- JIS X 0201
- ISO/IEC 2022
- CL, GL, CR, GR
- 符号化方式
- JIS X 0208, JIS 第1・第2水準漢字, JIS漢字
- 各種符号化方式(Shift_JIS, EUC-JP, ISO-2022-JP)
- ISO/IEC 8859, Latin-1
- Unicode, ISO/IEC 10646
- UTF-16, UTF-8
- JIS X 2013
JavaScriptにも対応したボットをRubyで書く
CapybaraとPoltergeistとPhantomJSを使えば、割と簡単にできそうな感じがする。
- https://github.com/jnicklas/capybara
- https://github.com/jonleighton/poltergeist
- http://phantomjs.org/
簡単なJavaScriptを実行した結果のHTMLに対して操作できるという所までは確認してますが、これが非同期処理などの複雑なJavaScriptに対してどこまでやりきれるかは未確認です。
また、Rubyで書けるのは良いのですが、実際の処理をPhantomJSが実行するため、Mechanizeを使った場合のようにWebMockなどを使ってテストを簡単に書けるわけではなさそうな所も不安です。
一方、Ghost DriverというPhantomJSをWebDriver APIに対応させるプロジェクトもありますが、PhantomJSのブランチを使う必要があるとかなんだとかで手を出していません。PhantomJSに取り込まれるという噂もあったりなかったり。
電話番号を電気通信番号指定状況に従って分割してみる
重い腰を上げてテストにかかる時間の短縮を試みる
とあるプロジェクトの通しテストについて、MRIとREEで設定を変えて時間を計ってみた。
その後、parallel_tests を試してみた。
.rbenv-vars
RUBY_HEAP_MIN_SLOTS=1000000 RUBY_HEAP_SLOTS_INCREMENT=1000000 RUBY_HEAP_SLOTS_GROWTH_FACTOR=1 RUBY_GC_MALLOC_LIMIT=600000000 RUBY_HEAP_FREE_MIN=2000000
ruby-1.8.7-p174
速度 0.97 倍。
- before: 798.858277
- after: 819.793473
ree-1.8.7-2009.09
速度 1.15 倍。
- before: 739.677229
- after: 642.832992
対MRIでみると、前1.08倍、後1.28倍。
parallel_tests
- 並列2: 397.472827
- 並列4: 343.886055
MRIデフォルトから比べると、並列2で2.00倍, 並列4で2.32倍(ivy i7 2GHz 2コア)。
ただし、並列実行を想定しないテストがあっていくつか失敗してる。
New Relic がどうやってメトリクスを集めているのか気になったのでちょっと調べてみた
Passenger の場合について簡単に調査。
PhusionPassenger.on_event(:starting_worker_process) で、NewRelic::Agent.after_fork を実行している。
NewRelic::Agent.after_fork は、Thread.new してワーカースレッドを作っている。
という事で、Passenger のワーカーインスタンスが作った Thread に NewRelic サーバへのリクエストを任せているという理解で良い気がする。
以下メモ。
newrelic_rpm-3.4.1/lib/new_relic/agent/agent.rb
- NewRelic::Agent::Agent#start
- -> NewRelic::Agent::Agent#check_config_and_start_agent
- -> NewRelic::Agent::Agent#start_worker_thread
- -> Thread.new
- -> NewRelic::Agent::Agent#deferred_work!
- -> Thread.new
- -> NewRelic::Agent::Agent#start_worker_thread
- -> NewRelic::Agent::Agent#check_config_and_start_agent
- -> NewRelic::Agent::Agent#after_fork
- -> NewRelic::Agent::Agent#start_worker_thread
- -> Thread.new
- -> NewRelic::Agent::Agent#deferred_work!
- -> Thread.new
- -> NewRelic::Agent::Agent#start_worker_thread
newrelic_rpm-3.4.1/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb
DependencyDetection.defer do @name = :passenger depends_on do defined?(PhusionPassenger) end executes do NewRelic::Agent.logger.debug "Installing Passenger event hooks." PhusionPassenger.on_event(:stopping_worker_process) do NewRelic::Agent.logger.debug "Passenger stopping this process, shutdown the agent." NewRelic::Agent.instance.shutdown end PhusionPassenger.on_event(:starting_worker_process) do |forked| # We want to reset the stats from the stats engine in case any carried # over into the spawned process. Don't clear them in case any were # cached. We do this even in conservative spawning. NewRelic::Agent.after_fork(:force_reconnect => true) end end end
newrelic_rpm-3.4.1/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb
module DependencyDetection module_function @@items = [] def defer(&block) item = Dependent.new item.instance_eval(&block) @@items << item end def detect! @@items.each do |item| if item.dependencies_satisfied? item.execute end end end ...
newrelic_rpm-3.4.1/lib/new_relic/control/frameworks/rails.rb
newrelic_rpm-3.4.1/lib/new_relic/control/instrumentation.rb
- NewRelic::Agent#add_instrumentation
- -> NewRelic::Control::Instrumentation#add_instrumentation
- -> NewRelic::Control::Instrumentation#load_instrumentation_files
- -> NewRelic::Control::Instrumentation#add_instrumentation
- NewRelic::Control#init_plugin
- -> install_instrumentation
- -> NewRelic::Control::Instrumentation#install_instrumentation
- -> NewRelic::Control::Instrumentation#_install_instrumentation
- -> NewRelic::Control::Instrumentation#load_instrumentation_files
- -> NewRelic::Control::Instrumentation#_install_instrumentation
Homebrew の patches で圧縮ファイルを指定する場合
patch の流れはざっくりと以下の様な感じ。
- curl で %03d-homebrew.diff という名前で保存する
- 圧縮されているか判別して適切な拡張子を付け足す(mv する)
- 圧縮されている場合は展開する
- %03d-homebrew.diff という名前のファイルを patch する
圧縮ファイルを展開する際にファイル名を指定しないため、圧縮ファイルの名前に書き換わる場合がある。
上記のパッチを使おうとすると、gunzip で展開されたファイルの名前がオリジナルの libiconv-1.13-ja-1.patch になってしまう。
というところまで分かった。
追記
-n でオリジナルの名前を使わない様にしたらよいのかな?