Bug 16974

Summary: callNextMethod() inefficiency
Product: R Reporter: Hervé Pagès <hpages>
Component: S4methodsAssignee: R-core <R-core>
Status: CLOSED FIXED    
Severity: normal CC: michafla
Priority: P5    
Version: R-devel (trunk)   
Hardware: All   
OS: All   

Description Hervé Pagès 2016-06-28 19:25:31 UTC
setClass("A", slots=c(stuff="ANY"))
setClass("B", contains="A")
setClass("C", contains="B")
a <- new("A")
b <- new("B")
c <- new("C")

setGeneric("foo", function(x) standardGeneric("foo"))
setMethod("foo", "A", function(x) "A")
setMethod("foo", "B", function(x) c(callNextMethod(x), "B"))
setMethod("foo", "C", function(x) c(callNextMethod(x), "C"))

system.time(replicate(1000, foo(a)))
# user system elapsed
# 0.012 0.000 0.012

system.time(replicate(1000, foo(b)))
# user system elapsed
# 0.108 0.000 0.108

system.time(replicate(1000, foo(c)))
# user system elapsed
# 0.910 0.000 0.911

A 9x slowdown for each nested call to callNextMethod!
One would expect this to scale linearly with the number of nested levels,
not exponentially.

Thanks,
H.
Comment 1 Michael Lawrence 2016-06-29 13:25:59 UTC
The cache did not work with chaining. Fixed, thanks.