興味深い質問だったので、自分で試してみました。
以下のスクリプトにおいて
func0がassign/getを使うバージョン。
func1が<<-を使うバージョン。
そしてfunc2では、対象のグローバル変数をローカル環境にまずコピーし、処理が全部終わってから書き戻すというのを試してみました。
R
1Rprof(tmp<-tempfile(), interval=0.01)
2
3rep <- 10000000
4
5count1 <- 0
6func0 <- function(){
7 for(i in 1:rep){
8 assign('count1', get("count1",env=.GlobalEnv) + 1, env=.GlobalEnv)
9 }
10}
11func0()
12cat(sprintf('count1=%d\n', count1))
13
14count1 <- 0
15func1 <- function(){
16 for(i in 1:rep){
17 count1 <<- count1 + 1
18 }
19}
20func1()
21cat(sprintf('count1=%d\n', count1))
22
23count1 <- 0
24func2 <- function(){
25 count1.local <- count1
26 for(i in 1:rep){
27 count1.local <- count1.local + 1
28 }
29 assign('count1', count1.local, env=.GlobalEnv)
30}
31func2()
32cat(sprintf('count1=%d\n', count1))
33
34Rprof(NULL)
35summaryRprof(tmp)
36
結果をサマライズしたものを示します。
$ R -q --slave --vanilla < ~/test.r |egrep 'count|func|total.time'
count1=10000000
count1=10000000
count1=10000000
self.time self.pct total.time total.pct
"func0" 4.52 26.65 15.86 93.51
"func1" 0.82 4.83 0.82 4.83
"func2" 0.27 1.59 0.28 1.65
total.time total.pct self.time self.pct
"func0" 15.86 93.51 4.52 26.65
"func1" 0.82 4.83 0.82 4.83
"func2" 0.28 1.65 0.27 1.59
やはりassignとgetの繰り返しは時間を食うようです。
そして、どうやら<<-より<-の方がだいぶん高速のようです。
func2()の所要時間はfun1()の1/3。<<-を使わずに高速化が達成できたと言えそうです。いかがでしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/05 13:11