2011-01-05 5 views
3
> system.time(sapply(rnorm(1000000,0,1), function (x) round(x,2))) 
    user system elapsed 
    2.78 0.11 2.89 
> system.time(round(rnorm(1000000,0,1),2)) 
    user system elapsed 
    0.29 0.00 0.30 

私はこれをRヒントの質問の答えを読んだ後に試していました。上記のケースでは、sapplyは同等の合成関数よりも遅くなるとは思っていませんでした。誰がなぜこれが当てはまるのか知っていますか?私が正しく理解すれば、サプリーはベクトル化し、最適に速く近くなります。サプリーと複合機能の速度比較

+2

Kohskeは右である:

は、あなたがそれにリストを与えた場合の比較します。サプリーは実際のベクトル化の錯覚または貧弱な代替物を作成するだけです。可能であれば、本質的にベクトル化された関数を使用してすべての変換を構築するようにしてください。 –

+2

'sapply'の主な目的は、ループの読みやすさを向上させ、タイピングを保存することです。 –

+0

参照:http://stackoverflow.com/questions/2275896/is-rs-apply-family-more-than-syntactic-sugar –

答えて

2

そこは何もしsapplyためにここにいない - あなただけそれを単一のベクター与える - ないベクトルのリストを、そしてsapplyはに結果を変換し、 (単一の列)マトリックス。

sapplyは結果を簡略化していますが、そうすることで配列を生成する必要があります。

system.time(sapply(list(rnorm(1000000,0,1)), function (x) round(x,2))) 
user system elapsed 
0.22 0.00 0.22 

system.time(sapply(rnorm(1000000,0,1), function (x) round(x,2))) 
user system elapsed 
4.21 0.00 4.21 
+1

'sapply'は、要素ごとにベクトルを操作する' lapply'を呼び出します。 – hadley

+0

ハドレーに感謝、私はここで何が起こっているのか正確には分かっていませんでしたが、余分な時間を要することは明らかです。 – mdsumner

+2

こんにちは、最初の(リスト)ケースは、for(i = 1)round(x [[i]]のようになります。ここでxはlist(rnorm(100000))です。 round(rnorm(100000))を呼び出すのと非常によく似ています。第2の場合は、for(i = 1:100000)round(x [i])のようになります。ここで、xはrnorm(100000)です。余分な時間は単純化によるものではなく、ループです。 – kohske

5

おそらく、ラップの単純なラッパーであるサプライは、ベクトル化されていません。このコードを試してみてください。

system.time(sapply(rnorm(10), function (x) {print(length(x)); round(x,2)})) 

を、ここでの実装を参照してください。https://svn.r-project.org/R/trunk/src/main/apply.c

関連する問題