私は現在クラスシステムを使用しているRパッケージを持っていますS3
.2つの異なるクラスとplot
、logLik
およびupdate
(モデル式の更新用)などの一般的なS3関数用のいくつかのメソッドがあります。if/else
の 2 つの引数に基づく継承またはディスパッチがないという事実により、すべての有効性チェックと構造体でコードがより複雑になったためS3
、パッケージを に変換することを考え始めましたS4
。S3
しかし、その後、 vsの長所と短所について読み始めましたが、S4
もうよくわかりません。S3 と S4 の効率性の問題に関するR ブロガーのブログ記事を見つけました。これは 5 年前のことなので、同じことをテストしました。
library(microbenchmark)
setClass("MyClass", representation(x="numeric"))
microbenchmark(structure(list(x=rep(1, 10^7)), class="MyS3Class"),
new("MyClass", x=rep(1, 10^7)) )
Unit: milliseconds
expr
structure(list(x = rep(1, 10^7)), class = "MyS3Class")
new("MyClass", x = rep(1, 10^7))
min lq median uq max neval
148.75049 152.3811 155.2263 159.8090 323.5678 100
75.15198 123.4804 129.6588 131.5031 241.8913 100
したがって、この単純な例でS4
は、実際には少し高速でした。次に、 vsの使用に関するSO の質問を読みました。特に@joshua-ulrichの答えは、S3
S4
S3
S4
スロットの変更には、完全なオブジェクトのコピーが必要です
モデルの対数尤度を最適化するときに、反復ごとにオブジェクトを更新するという私のケースを考えると、それは大きな問題のように感じます。グーグルで調べた後、R 3.0.0 で変更されているように見える、この問題に関するJohn Chambers の投稿を見つけました。
したがってS4
、コードを明確にするためにクラスを使用することは有益だと思いますが (たとえば、メイン モデル クラスから継承するより多くのクラス)、および有効性チェックなどのために、すべての作業の価値があるかどうか疑問に思っています。パフォーマンス?では、パフォーマンスに関して、 と の間に実際のパフォーマンスの違いはS3
ありS4
ますか? 他に考慮すべきパフォーマンスの問題はありますか? それとも、この問題について一般的に何かを言うことさえ可能ですか?
編集: @DWin と @g-grothendieck が示唆したように、上記のベンチマークでは、既存のオブジェクトのスロットが変更された場合を考慮していません。したがって、実際のアプリケーションにより関連する別のベンチマークを次に示します (例の関数は、モデル内のいくつかの要素の get/set 関数である可能性があり、対数尤度を最大化するときに変更されます)。
objS3<-structure(list(x=rep(1, 10^3), z=matrix(0,10,10), y=matrix(0,10,10)),
class="MyS3Class")
fnS3<-function(obj,a){
obj$y<-a
obj
}
setClass("MyClass", representation(x="numeric",z="matrix",y="matrix"))
objS4<-new("MyClass", x=rep(1, 10^3),z=matrix(0,10,10),y=matrix(0,10,10))
fnS4<-function(obj,a){
obj@y<-a
obj
}
a<-matrix(1:100,10,10)
microbenchmark(fnS3(objS3,a),fnS4(objS4,a))
Unit: microseconds
expr min lq median uq max neval
fnS3(objS3, a) 6.531 7.464 7.932 9.331 26.591 100
fnS4(objS4, a) 21.459 22.393 23.325 23.792 73.708 100
ベンチマークは、64 ビット Windows 7 の R 2.15.2 で実行されます。したがって、ここでS4
は明らかに遅いです。