41

Basically, when there are many arguments in setMethod or (setGeneric) it works very slowly.

Here is a basic example:

setClassUnion(name = "mNumeric", members = c("missing", "numeric"))
setClass(Class = "classA", representation = representation(ID = "character"))

setGeneric("foo", function(r, i, ..., m = 1, D = 1, U = 999, K = 0.005, 
                           E1 = -5, E2 = 5, E3 = 1, E4 = 1, E5 = 1, E6 = 1,
                           A1 = -5, A2 = 5, A3 = 1, A4 = 1, A5 = 1, A6 = 1)
                  {standardGeneric ("foo")})

setMethod(f = "foo", 
  signature = c(r = "ANY", i = "classA", m = "mNumeric", D = "mNumeric", 
                U = "mNumeric", K = "mNumeric", E1 = "mNumeric", E2 = "mNumeric",
                E3 = "mNumeric", E4 = "mNumeric", E5 = "mNumeric", E6 = "mNumeric", 
                A1 = "mNumeric", A2 = "mNumeric", A3 = "mNumeric", A4 = "mNumeric", 
                A5 = "mNumeric", A6 = "mNumeric"),
  function(r, i, ..., m, D, U, K, E1, E2, E3, E4, E5, E6, A1, A2, A3, A4, A5, A6)
    {print("Function can made it here..")})

#Program hangs after the following code. (at least five minutes)
foo(r = 1, i = new("classA", ID = "ID1"))

I observe that this is not related to the class. You can put a numeric class into r and it will do the same. If I trim the number of arguments it will work.

I suspect that it tries "to find an inherited method for function ‘foo’ for signature ‘"numeric", "classA", "missing", ..." and this causes R to hang. HERE is a good discussion of this topic.

Because if I run same code with less parameters it works:

setGeneric("foo", function(r, i, ..., m = 1, D = 1, U = 999, K = 0.005, 
                           E1 = -5, E2 = 5, E3 = 1, E4 = 1)
          {standardGeneric ("foo")})

setMethod(f = "foo", 
  signature = c(r = "ANY", i = "classA", m = "mNumeric", D = "mNumeric", 
                U = "mNumeric", K = "mNumeric", E1 = "mNumeric", E2 = "mNumeric",
                E3 = "mNumeric", E4 = "mNumeric"),
  function(r, i, ..., m, D, U, K, E1, E2, E3, E4)
  {print("Function can made it here..")})

foo(r = 1, i = new("classA", ID = "ID1"))

Why this happens? Any ideas will be appreciated.

smci
  • 32,567
  • 20
  • 113
  • 146
HBat
  • 4,873
  • 4
  • 39
  • 56
  • 4
    I tested without the E-variables - not 5 minutes, but still remarkably long. I observed that only the first time when foo is called it takes so long. The second time foo is really fast. I tried to replace `print` by `stop` and traced it by `options(error=traceback)` to see all the call steps - but everything seems fine, just 3 calls. So this is really weird... – Patrick Roocks Sep 04 '14 at 08:37
  • 2
    @PatrickRoocks Thanks for confirming. I believe the method look-up takes so much time (as explained [here](http://stackoverflow.com/a/16386422/2275286)). As you said it is weird, one cannot write any S4 function that has more than 5-6 inputs (and iterates within a new environment every time) if this is the case. – HBat Sep 04 '14 at 17:33
  • Can you explicitly time the code in your question so that potential answers/work-arounds can be compared on the basis of reducing the hang-up time? For instance by changing your last line to `system.time(foo(r = 1, i = new("classA", ID = "ID1"))`. – Brian Albert Monroe Sep 16 '15 at 14:40

1 Answers1

1

I had a similar problem. S4 seems the all possible combinations of signature. Which slows things down to a crawl. The solution is to have as little elements in the signature as possible.

You can find the details here https://stat.ethz.ch/pipermail/r-devel/2015-May/071092.html

Thierry
  • 18,049
  • 5
  • 48
  • 66