teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

速度について

2018/11/11 10:30

投稿

KojiDoi
KojiDoi

スコア13727

answer CHANGED
@@ -8,4 +8,66 @@
8
8
  ```
9
9
 
10
10
  ただ、中身が複雑になってくると、みにくくはなります。
11
- よほどスピードが求められるのでない限り、素直にforループを使ったほうがいいと思います。
11
+ よほどスピードが求められるのでない限り、素直にforループを使ったほうがいいと思います。
12
+
13
+ #速度について
14
+ 「よほどスピードが求められるのでない限り」とか何となく書いてしまいましたが、実際のところ実行時間に差が出るものか試してみました。
15
+ 質問文にある程度の組み合わせ量ではどのみち差が出ないので、ループ回数をふやしての実験です。
16
+ ```
17
+ Rprof(tmp<-tempfile(), interval=0.01)
18
+
19
+ #ii <- 1:3000
20
+ #jj <- seq(11,15,2)
21
+ #kk <- seq(101,110,3)
22
+ ii <- 1:100
23
+ jj <- 1:100
24
+ kk <- 1:100
25
+
26
+ func1 <- function(){
27
+ for (i in ii) {
28
+ for (j in jj) {
29
+ for (k in kk) {
30
+ # print(paste(paste(i,j),k))
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ func2 <- function(){
37
+ sapply(ii, function(i){
38
+ sapply(jj, function(j){
39
+ sapply(kk, function(k){
40
+ # print(paste(i,j,k))
41
+ })
42
+ })
43
+ })
44
+ return(invisible())
45
+ }
46
+
47
+
48
+
49
+ func3 <- function(){
50
+ apply(expand.grid(ii, jj, kk), 1, function(x){
51
+ # print(paste(x[1],x[2],x[3]))
52
+ })
53
+ return(invisible())
54
+ }
55
+
56
+ func1()
57
+ func2()
58
+ func3()
59
+
60
+ Rprof(NULL)
61
+ profres <- summaryRprof(tmp)
62
+ print(profres$by.total[grep("func[1-3]", rownames(profres$by.total)),])
63
+ ```
64
+
65
+ 結果は次の通り。
66
+ ```
67
+ > source("test.r")
68
+ total.time total.pct self.time self.pct
69
+ "func3" 3.59 62.87 0.00 0.00
70
+ "func2" 2.06 36.08 0.00 0.00
71
+ "func1" 0.06 1.05 0.06 1.05
72
+ ```
73
+ なんとforループがダントツでした。expand.gridではいったんすべての組み合わせをリストアップしたリストを作るため、そのオーバーヘッドが生じていると想像されます。