2013-08-07 13 views
6

Düzenli olarak zaman serilerinin haddelemesini buluyorum (özellikle de araçlar) ve rollmean'un rollapply'dan daha hızlı olduğunu ve align = 'right' yöntemlerinin rollmeanr sarıcılardan daha hızlı olduğunu görmeye şaşırdım.Rollmpply'den (kod-bilge) daha hızlı rollmean yapan nedir?

Bu hıza nasıl eriştiler? Ve neden rollmeanr() sarıcı kullanırken bazılarını kaybeder?

Bazı arka plan: rollapplyr(x, n, function(X) mean(X)) kullanıyordum, ancak son zamanlarda rollmean kullanarak birkaç örnek üzerinde oldu. Belgeler,(function argümanın parçası olmadan not) rollmean kullanır, bu yüzden performansta çok fazla farklılık olacağını düşünmüyordum, ancak rbenchmark dikkate değer farklılıklar ortaya çıkardı.

require(zoo) 
require(rbenchmark) 

x <- rnorm(1e4) 
r1 <- function() rollapplyr(x, 3, mean) # uses rollmean 
r2 <- function() rollapplyr(x, 3, function(x) mean(x)) 
r3 <- function() rollmean(x, 3, na.pad = TRUE, align = 'right') 
r4 <- function() rollmeanr(x, 3, align = "right") 

bb <- benchmark(r1(), r2(), r3(), r4(), 
      columns = c('test', 'elapsed', 'relative'), 
      replications = 100, 
      order = 'elapsed') 

print(bb) 

Ben rollmean(x, n, align = 'right') özellikle hızlı olduğunu bulmak için sürpriz oldu - ve benim rollapply(x, n, function(X) mean(X)) yaklaşımından daha ~ 40x daha hızlı.

test elapsed relative 
3 r3() 0.74 1.000 
4 r4() 0.86 1.162 
1 r1() 0.98 1.324 
2 r2() 27.53 37.203 

fark veri setinin boyutu büyüdükçe daha büyük olsun gibi görünüyor. Yukarıdaki kodda sadece x (rnorm(1e5) için) boyutunu değiştirdim ve testi yeniden çalıştırdım ve işlevler arasında daha da büyük bir fark vardı.

test elapsed relative 
3 r3() 13.33 1.000 
4 r4() 17.43 1.308 
1 r1() 19.83 1.488 
2 r2() 279.47 20.965 

ve x <- rnorm(1e6)

test elapsed relative 
3 r3() 44.23 1.000 
4 r4() 54.30 1.228 
1 r1() 65.30 1.476 
2 r2() 2473.35 55.920 

Nasıl için

bu yaptın? Ayrıca bu en uygun çözüm mü? Elbette, bu hızlı ama bunu yapmak için daha hızlı bir daha hızlı yolu var mı?

(Not: genel olarak benim zaman serisi hemen hemen her zaman xts nesnelerdir - Bu önemli?)

+2

i yardım sayfasını okudum @DWIN – eddi

+2

sonuçlanır. Aldığınız metni '? Rollapplyr'' gördüm ama nedenini açıklamıyor. Daha sonra “rollmean” a gittim ve “Bu fonksiyonlar sırasıyla haddeleme araçları, maksimumlar ve medyanları hesaplıyorlar ve bu yüzden“ rolllapply ”e benziyorlar ama hız için optimize ediliyorlar. Ayrıca, ne rollmean (x, n, align = 'right') 'nin neden rollmeanr (x, n)' den daha hızlı olduğunu açıklamamaktadır. Son olarak, hiçbiri performans boşluklarının neden veri büyüklüğüyle büyüdüğünü açıklamıyor. – ricardo

+0

"Neden" için neyin yeterli bir açıklaması var? Cevap için "hıza ihtiyaç" nasıl değil? –

cevap

7

demek genel haddeleme fonksiyonunun hesaplanması daha hızlıdır haddeleme Bilgisayar, ilki hesaplamak daha kolaydır çünkü.

(a2 + a3 + ... + an)/(n-1) = (a1 + a2 + ... + a(n-1))/(n-1) + (an - a1)/(n-1) 

ve bu kaldıraçlı nasıl görebilirsiniz: Genel bir haddeleme fonksiyonunun hesaplanması zaman nedeniyle basit kimlik, mean için yapmak gerekmez, hangi tekrar tekrar her pencere üzerinde fonksiyonunu hesaplamak zorunda getAnywhere(rollmean.zoo)'a bakarak.

Daha hızlı bir haddeleme demek istiyorsanız, caTools numaralı telefondan 'u kullanın, bu da C'yi çok daha hızlı bir şekilde yapar (ayrıca çok daha iyi ölçeklendirir, böylece veri boyutu arttıkça daha da hızlı olur). Eğer çok daha hızlı için caTools` `dan` runmean` denemek isteyebilirsiniz

library(microbenchmark) 
library(caTools) 
library(zoo) 

x = rnorm(1e4) 
microbenchmark(runmean(x, 3, endrule = 'trim', align = 'right'), 
       rollmean(x, 3, align = 'right')) 
#Unit: microseconds 
#            expr  min  lq  median  uq  max neval 
# runmean(x, 3, endrule = "trim", align = "right") 631.061 740.0775 847.5915 1020.048 1652.109 100 
#     rollmean(x, 3, align = "right") 7308.947 9155.7155 10627.0210 12760.439 16919.092 100 
+0

Ayrıca, xts nesnelerle iyi çalışan TTR :: runMean' da var. –