2016-06-14 21 views
1

私はこのコードを持っており、私は最適化を知らないので、それは私の最高のパフォーマンスだと思います。あなたはオプトマイゼーションリストのために道を開いていますか?大きなリストの最適化

require(dplyr); require(rgeos); require(sp) 
sim.polygons = function(objects, vertex){ 
    polygons = NULL 
    for(i in 1:objects) polygons[[i]] = matrix(runif(vertex*2), ncol = 2) 
    return(polygons) 
} 

test = function(lista1, lista2, progress = F){ 
    lista1 = lapply(lista1, as, Class = "gpc.poly") 
    lista2 = lapply(lista2, as, Class = "gpc.poly") 
    res = matrix(0, nrow = length(lista2), ncol = length(lista1)) 
    for(k in 1 : length(lista1)){ 
    for(l in 1 : length(lista2)){ 
     res[l, k] = area.poly(intersect(lista1[[k]], lista2[[l]])) #very slow 
    } 
    if(progress == T) print(k) 
    } 
    res 
} 
#exemple 
a = sim.polygons(50, 3) #in my problem, objects = 144 and vertex = 3 
b = sim.polygons(100, 3) #objects = 114^2 and vertex = 3 

test(a, b, T) 
+0

一般に、 'for'ループをRのベクトル化された操作に切り替えるほうが速いことがあります。ネストされた' for'ループを、はるかに高速なベクトル化された操作に変換する方法を示す2つのチュートリアルがあります。http ://www.r-bloggers.com/how-to-use-vectorization-to-streamline-simulations/&https://www.datacamp.com/community/tutorials/tutorial-on-loops-in-r –

答えて

2

この問題はforeachdoParallelと並列に実装するのはとても簡単です。この例では、この例のコメントに記述した問題のループとforeachループを比較します。

require(dplyr); require(rgeos); require(sp) 
sim.polygons = function(objects, vertex){ 
    polygons = NULL 
    for(i in 1:objects) polygons[[i]] = matrix(runif(vertex*2), ncol = 2) 
    return(polygons) 
} 

test = function(lista1, lista2, progress = F){ 
    lista1 = lapply(lista1, as, Class = "gpc.poly") 
    lista2 = lapply(lista2, as, Class = "gpc.poly") 
    res = matrix(0, nrow = length(lista2), ncol = length(lista1)) 
    for(k in 1 : length(lista1)){ 
    for(l in 1 : length(lista2)){ 
     res[l, k] = area.poly(intersect(lista1[[k]], lista2[[l]])) #very slow 
    } 
    if(progress == T) print(k) 
    } 
    res 
} 

a = sim.polygons(144, 3) #in my problem, objects = 144 and vertex = 3 
b = sim.polygons(114, 3) #objects = 114^2 and vertex = 3 

system.time(res<-test(a, b, T)) 
user system elapsed 
34.66 0.02 34.67 

library(foreach) 
library(doParallel) 
cl<-makeCluster(6) 
registerDoParallel(cl) 
getDoParWorkers() #6 

foreach(i=1:6) %dopar% library(rgeos) 

test.par = function(lista1, lista2, progress = F){ 
    lista1 = lapply(lista1, as, Class = "gpc.poly") 
    lista2 = lapply(lista2, as, Class = "gpc.poly") 
    res = matrix(0, nrow = length(lista2), ncol = length(lista1)) 
    res<-foreach(k= 1 : length(lista1), .combine = "cbind") %:% 
    foreach(l = 1 : length(lista2), .combine = 'c') %dopar% #not as slow 
     area.poly(intersect(lista1[[k]], lista2[[l]])) 
    } 


system.time(res.par<-test.par(a, b, T)) 
user system elapsed 
7.97 0.46 15.51 

dim(res) 
[1] 114 144 

dim(res.par) 
[1] 114 144 

sum(rowSums(res-res.par)) 
[1] 0 

この実装は、6コアで実行される計算時間を半分に削減します。あなたの結果は多かれ少なかれコアによって変わるかもしれません。ループ内で巧妙なプログラミングから得られる可能性はまだまだ高いです。

関連する問題