2012-05-17 6 views
14

私はt_time_tracker(woohoo!)と呼ばれる最初の宝石を開発しています。すべてが発展していた。私はそれが同じくらい私はおそらくダウンできるだけへの実行時間を削減することができたとしてoptomized:私の宝石はなぜロードに時間がかかりますか?

t_time_tracker[master*]% time ruby -Ilib ./bin/t_time_tracker 
You're not working on anything 
0.07s user 0.03s system 67% cpu 0.141 total 

(これは私のアプリの「Hello World」のである - パラメータなしでそれを呼び出すだけでプリントアウトする「あなた」何でも作業していない」)

約10分の1秒で、私のCPUの67%を使っています。それはかなり瞬時に感じます。のは、それを構築してみましょう:

$ gem build t_time_tracker.gemspec 
$ gem install ./t_time_tracker-0.0.0.gem 

とインストールされたバイナリとまったく同じことを行います。

$ time t_time_tracker 
You're not working on anything 
t_time_tracker 0.42s user 0.06s system 93% cpu 0.513 total 

0.5秒!それはどこから来ましたか?!

t_time_tracker[master*]% time ruby ./bin/t_time_tracker 
(starting binary) 
(require 'time' and 'optparse') 
0.041432 
(before `require 't_time_tracker') 
0.497135 
(after `require 't_time_tracker') 
(Gem.loaded_specs.keys = t_time_tracker) 
(initializing TTimeTracker class) 
You're not working on anything 
ruby ./bin/t_time_tracker 0.44s user 0.07s system 91% cpu 0.551 total 

さてさて、そう `必要「t_time_tracker」行が犯人であると思われる:いくつかのデバッグ出力を追加し、ボトルネックがどこにあるか確認するために、開発のバイナリからのシステムの宝石が含まれてみましょう。 irbでもう一度試してみましょう。

$ irb 
>> t=Time.now; require 't_time_tracker'; puts Time.now-t 
0.046792 
=> nil 

...何ですか?しかし、それはちょうど半分を取っていた!

$ gem build t_time_tracker.gemspec 
$ gem install ./t_time_tracker-0.0.0.gem 
$ time t_time_tracker 
(starting binary) <---noticeable half second delay before this line shows up 
(require 'time' and 'optparse') 
0.050458 
(before `require 't_time_tracker') 
0.073789 
(after `require 't_time_tracker') 
(Gem.loaded_specs.keys = t_time_tracker) 
(initializing TTimeTracker class) 
You're not working on anything 
t_time_tracker 0.42s user 0.06s system 88% cpu 0.546 total 

ええ、0.5秒遅れはどこから来ていますか?私は通常気にしませんが、これは私が何をやっているかを更新するために約50回を呼び出すものです。 50 * 0.5秒* 365日* 70年=失われた人生の15日間。

システム情報:

はMac OS X 10.7.3。 2 GHz Intel Core 2 Duo。 4 GB RAMルビ1.9.2p290。

% gem -v 
1.8.10<---noticeable half second delay before this line shows up 
% gem list | wc -l 
209 
+3

1.9.3のようなパフォーマンスは何ですか? –

+0

興味深い... 'rvm 1.9.3 && gem install t_time_tracker'は私に超高速実行時間(合計0.100秒)を与えてくれますが、これは' gem list | wc -l' = 7. Hmmm ... – cgenco

+0

'gem install rails'の後、' gem list | wc-l'= 33であり、「時間t」は平均約0.21である。ソリューションは単に "多くの宝石をインストールしないでください"ですか? – cgenco

答えて

2

は、しばらくして:

  • はそれは多くの比較的高価なライブラリをロードするでしょう'yaml'を介して '時間'のように。通常は、ルビに比べて遅いので、気にしません。多くのスクリプトの実行時間に比べて遅くはありません。
  • インストールされているすべてのgemをスキャンし、最新のgemspecをメモリにロードします。あなたにはたくさんの宝石があれば、これは長い時間がかかりました。

これらの問題は引き続き発生する場合があります。しかし、は常ににRubyGemsのオーバーヘッドがあります。実際にパフォーマンスが必要な場合は、自分でロード・パスを設定してください。ご存じのRubyGemsを使用しないRubyは非常に高速です。あなたの宝石がインストールされている場所を確認するには

gem list -d YOUR_GEM_NAME 

あなたは、インストールディレクトリが表示されます。

たくさんですが、あなたは別のスクリプトでこれをラップすることができるはず
time ruby -IINSTALL_DIR/gems/GEM_NAME-VERSION/lib INSTALL_DIR/gems/GEM_NAME-VERSION/bin/t_time_tracker 

、このようなものは、(それをt_time_tracker名)::INSTALL_DIR /宝石/ GEM_NAME-VERSIONはとても実行してみてくださいにあなたの逸品になります

その後
#!/usr/bin/env ruby -IINSTALL_DIR/gems/GEM_NAME-VERSION/lib 
load 'INSTALL_DIR/gems/GEM_NAME-VERSION/bin/t_time_tracker' 

chmod +x t_time_tracker 
time ./t_time_tracker 

そして、あなたのPATHに沿って任意の場所にそのファイルを置きます。 RubyGemsは自動的に行いますが、もちろんRubyGemsのオーバーヘッドを受け入れます。

+0

素晴らしいですが、他のユーザーに配布されている宝石はどうですか? – sixty4bit

0

「ローカル」の宝石があるからでしょうか。ルビーは彼を拾う前に他のパスをチェックする必要があります。

例えば、あなたはファイルjson.rbと宝石がインストールと呼ばれるグローバルと呼ばれるJSONを持っているかどう

require 'json' 

を行うとき、彼は最初の宝石を見つけて、それをロードします:)。ローカルパスが最後にロードされます。あなたが宝石をバンドルしてインストールすれば、宝石の場所が違うだけで、大幅なスピードの向上が見られます。私は、開発におけるこの読み込み時間の不足についてはあまり心配しません。

0

あなたの宝石の中で使われている$LOAD_PATHが原因である可能性があります。理想的には、あなたのlibフォルダのパスが最初にその配列にあります。私は、過去の(そしておそらく現在)で、主に二つの理由のためにロードに時間を取られRubyGemsのがありますが、これを見たので、

関連する問題