2010-12-06 9 views
19

私はすべての機能を記述しようとしているときはいつも、require(<pkgname>)を使用していますが、代わりに::を使用することを常に考えていました。存在しないパッケージの名前を指定するとエラーを返すlibraryとは異なり、requirelibraryよりもよく実行すると、requireが警告を返し、FALSEを返します。R書くスタイル - 必要と対::

一方、requireはパッケージ全体を読み込んでいます(少なくとも私もそうだと思いますが)。オペレータが変数を取得するので、スピードの違いがまず私の心に来ました。 ::requireより速くなければなりません。

そして、私はそれをチェックするために、いくつかの分析をした - 私は、それぞれrequire::で、foreignパッケージからread.systat機能をロードする2つの簡単な関数を書いて、それ故にforeignパッケージに同梱、複製された機能の1000倍というIris.sydデータセットをインポートしますそれぞれ(恥知らずに恣意的であった)、そして...いくつかの数字を突っ込んだ。

奇妙なことに、私はユーザーCPUと経過時間に大きな違いがありましたが、システムCPUの点では大きな違いはありませんでした。そしてさらに奇妙な結論:::は実際には遅いです! ::のドキュメントは非常に鈍いです。ソースを見るだけで、::の方が優れているはずです。

#!/usr/local/bin/r 

## with require 
fn1 <- function() { 
    require(foreign) 
    read.systat("Iris.syd", to.data.frame=TRUE) 
} 

## times 
n <- 1e3 

sink("require.txt") 
print(t(replicate(n, system.time(fn1())))) 
sink() 

ダブルコロン

#!/usr/local/bin/r 

## with :: 
fn2 <- function() { 
    foreign::read.systat("Iris.syd", to.data.frame=TRUE) 
} 

## times 
n <- 1e3 


sink("double_colon.txt") 
print(t(replicate(n, system.time(fn2())))) 
sink() 

グラブCSVデータhereを必要とします。いくつかの統計情報:

user CPU:  W = 475366 p-value = 0.04738 MRr = 975.866 MRc = 1025.134 
system CPU: W = 503312.5 p-value = 0.7305 MRr = 1003.8125 MRc = 997.1875 
elapsed time: W = 403299.5 p-value < 2.2e-16 MRr = 903.7995 MRc = 1097.2005 

MRRはrequire::のためのMRC前掲の平均順位です。私はここで何か間違っていたに違いない。それはちょっと意味がありません... ::の実行時間は速いようですね!!!私は何かをねじったかもしれません、あなたはそのオプションを捨てるべきではありません...

OK ...私はいくつかの違いがあることを確認するために私の時間を無駄にした、と私は完全に役に立たない分析を行った、バックの質問に:

"機能を書くときはなぜ1は::requireを好むはずです?"

=)

+0

は、パッケージ内のスタンドアロン関数や機能のためにこれは、比較? – hadley

+0

また、通常は、スクリプトの先頭に一度()を必要とし、すべての関数呼び出しで一度は必要としません。 – hadley

+1

スタンドアロン機能用です。私はWebアプリケーションを開発しています。そしてRApacheは各HTTPリクエストで新しいRセッションを開始するので、私は不必要なサーバーの負荷を避けようとしています。この例は不適切です。一度ファイルを読み込んだら、ジョブは終了しましたが、AJAX呼び出しのある対話型Webアプリケーションでは、これは非常に非効率的です。 – aL3xa

答えて

12

「なぜ1は、上で::を要求好む必要があります関数を書くときに? "

私は通常、原因私は、コードに入る前に、フロントまで利用可能ではないパッケージの可能性に対処することができます素敵TRUE/FALSE返り値にrequireを好みます。分析の途中ではなく、できるだけ早くクラッシュしてください。

私は、正しいバージョンの関数を使用しているかどうかを確認する必要がある場合にのみ::を使用します。名前をマスクしている他のパッケージのバージョンではありません。一方

速度差が私の心に最初 来たので は、(少なくとも 私はそう願っています)負荷全体のパッケージを必要としながら、::演算子は、パッケージから 変数を取得します。 ::より速くなければなりません 必要以上に。

私はあなたがthe first page of its manualに応じforeignパッケージで使用される遅延読み込みの影響を無視することができると思います。本質的に、遅延ロードを使用するパッケージは、オブジェクトが初めて呼び出されるまで、関数などのオブジェクトのロードを遅延させます。だから、あなたがあなたの引数「::が必要以上に速くなければならない」という言い方は、必ずforeignrequireを付けてメモリにすべての内容をロードしていないため、必ずしも真ではありません。遅延ロードの詳細については、RNews、Volume 4、Issue 2のProf. Ripley's articleを参照してください。

+0

あなたはそうです...これはパッケージ依存の問題かもしれません。ああ、参考に感謝します。 – aL3xa

6

パッケージをロードする時間は、ほとんどの場合、あなたが書いたコード前のことではありましたが、この場合は明快にすることが最も重要です。開始時requireまたはlibraryへの呼び出しを持つ

スクリプトの場合

は、あなたがすぐに必要なパッケージのかを知ることができます。

は同様に、機能の開始時にrequire(またはHmiscrequirePackageまたはggplot2try_requireのようなラッパー)を呼び出すと、あなたはそのパッケージを使用する必要があることを示すの最も明白な方法です。あなたは、パッケージ–の間で名前の競合をしているとき

::は例のために確保されなければならない例えば、

Hmisc::is.discrete 

plyr::is.discrete 
関連する問題