Bug 16061 - vapply can be made more efficient
Summary: vapply can be made more efficient
Alias: None
Product: R
Classification: Unclassified
Component: Low-level (show other bugs)
Version: R 3.1.1
Hardware: All All
: P5 enhancement
Assignee: R-core
Depends on:
Reported: 2014-11-06 03:27 UTC by Peter Haverty
Modified: 2014-12-01 14:03 UTC (History)
1 user (show)

See Also:

modified apply.c file from R 3.1.1 defining vapply2 (17.42 KB, text/x-csrc)
2014-11-06 03:27 UTC, Peter Haverty
Vignette showing relative speed of vapply and tests. (15.95 KB, text/html)
2014-11-06 03:29 UTC, Peter Haverty

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Haverty 2014-11-06 03:27:58 UTC
Created attachment 1682 [details]
modified apply.c file from R 3.1.1 defining vapply2

vapply has unnecessary overhead related to the method used for copying result data into the final result array. The data copying loop checks the type of the result on every iteration, rather than once, outside the loop. Additionally, using memcpy, where possible, simplifies the code and provides the opportunity for the compiler to specify a more efficient copying strategy.

Speed improvements with trivial functions and large input have been in the 8-20% range on various systems with gcc 4.3 and 4.4
Comment 1 Peter Haverty 2014-11-06 03:29:49 UTC
Created attachment 1683 [details]
Vignette showing relative speed of vapply and tests.
Comment 2 Martin Maechler 2014-12-01 11:13:24 UTC
Your vignette uses the extreme case where FUN.VALUE is of length() 2e5 ... where using memcpy() instead of a for() loop is of course very very much more efficient.

OTOH, the typical use case has  length(FUN.VALUE) == 1,
so I have decided to use memcpy() whenever the length differs from one,
and in the very common case of 1, use a simplified version of the current code.

This only bloats the source code very mildly and should be (slightly) more efficient even in the very common use case (length == 1).
Comment 3 Martin Maechler 2014-12-01 14:03:51 UTC
svn rev  67091 :
Committed the version which special cases "length 1" and otherwise uses your solution -- with switch() however, instead of  if(.) .. else if(..) .. else if(..)