[Rcpp-commits] r4083 - in pkg/Rcpp: . inst/include/Rcpp inst/include/Rcpp/hash src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Dec 5 19:00:12 CET 2012
Author: romain
Date: 2012-12-05 19:00:12 +0100 (Wed, 05 Dec 2012)
New Revision: 4083
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/inst/include/Rcpp/cache.h
pkg/Rcpp/inst/include/Rcpp/hash/IndexHash.h
pkg/Rcpp/src/cache.cpp
Log:
caching the hash table internal data
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2012-12-05 17:41:52 UTC (rev 4082)
+++ pkg/Rcpp/ChangeLog 2012-12-05 18:00:12 UTC (rev 4083)
@@ -1,3 +1,9 @@
+2012-12-05 Romain Francois <romain at r-enthusiasts.com>
+
+ * src/cache.cpp: added get_cache
+ * include/Rcpp/hash/IndexHash.h: use a cached integer vector for
+ the hash table payload. The cache vector increases as needed.
+
2012-12-05 JJ Allaire <jj at rstudio.org>
* src/Attributes.cpp: use code generation for compileAttributes
Modified: pkg/Rcpp/inst/include/Rcpp/cache.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/cache.h 2012-12-05 17:41:52 UTC (rev 4082)
+++ pkg/Rcpp/inst/include/Rcpp/cache.h 2012-12-05 18:00:12 UTC (rev 4083)
@@ -2,7 +2,7 @@
//
// cache.h: Rcpp R/C++ interface class library --
//
-// Copyright (C) 2009 - 2011 Dirk Eddelbuettel and Romain Francois
+// Copyright (C) 2009 - 2012 Dirk Eddelbuettel and Romain Francois
//
// This file is part of Rcpp.
//
@@ -30,6 +30,9 @@
}
}
-extern "C" SEXP rcpp_init_cached_functions(SEXP) ;
+extern "C" {
+ SEXP rcpp_init_cached_functions(SEXP) ;
+ int* get_cache( int ) ;
+}
#endif
Modified: pkg/Rcpp/inst/include/Rcpp/hash/IndexHash.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/hash/IndexHash.h 2012-12-05 17:41:52 UTC (rev 4082)
+++ pkg/Rcpp/inst/include/Rcpp/hash/IndexHash.h 2012-12-05 18:00:12 UTC (rev 4083)
@@ -24,6 +24,20 @@
#ifndef RCPP__HASH__INDEX_HASH_H
#define RCPP__HASH__INDEX_HASH_H
+#if ( defined(HASH_PROFILE) && defined(__APPLE__) )
+ // only mac version for now
+ #include <mach/mach_time.h>
+ #define ABSOLUTE_TIME mach_absolute_time
+ #define RCPP_PROFILE_TIC start = ABSOLUTE_TIME() ;
+ #define RCPP_PROFILE_TOC end = ABSOLUTE_TIME() ;
+ #define RCPP_PROFILE_RECORD(name) profile_data[#name] = end - start ;
+#else
+ #define RCPP_PROFILE_TIC
+ #define RCPP_PROFILE_TOC
+ #define RCPP_PROFILE_RECORD(name)
+#endif
+#define RCPP_USE_CACHE_HASH
+
namespace Rcpp{
namespace sugar{
@@ -37,14 +51,33 @@
typedef typename traits::storage_type<RTYPE>::type STORAGE ;
typedef Vector<RTYPE> VECTOR ;
- IndexHash( SEXP table ) : n(Rf_length(table)), m(2), k(1), src( (STORAGE*)dataptr(table) ), data(), size_(0) {
+ IndexHash( SEXP table ) : n(Rf_length(table)), m(2), k(1), src( (STORAGE*)dataptr(table) ), size_(0)
+ , data()
+ #ifdef HASH_PROFILE
+ , profile_data()
+ #endif
+ {
+ RCPP_PROFILE_TIC
int desired = n*2 ;
while( m < desired ){ m *= 2 ; k++ ; }
- data.resize( m ) ;
+ #ifdef RCPP_USE_CACHE_HASH
+ data = get_cache(m) ;
+ #else
+ data.resize( m ) ;
+ #endif
+ RCPP_PROFILE_TOC
+ RCPP_PROFILE_RECORD(ctor_body)
+
}
inline IndexHash& fill(){
+ RCPP_PROFILE_TIC
+
for( int i=0; i<n; i++) add_value(i) ;
+
+ RCPP_PROFILE_TOC
+ RCPP_PROFILE_RECORD(fill)
+
return *this ;
}
@@ -84,17 +117,49 @@
int n, m, k ;
STORAGE* src ;
- std::vector<int> data ;
int size_ ;
+ #ifdef RCPP_USE_CACHE_HASH
+ int* data ;
+ #else
+ std::vector<int> data ;
+ #endif
+ #ifdef HASH_PROFILE
+ mutable std::map<std::string,int> profile_data ;
+ mutable uint64_t start ;
+ mutable uint64_t end ;
+ #endif
+
template <typename T>
SEXP lookup__impl(const T& vec, int n) const {
+ RCPP_PROFILE_TIC
+
SEXP res = Rf_allocVector(INTSXP, n) ;
+
+ RCPP_PROFILE_TOC
+ RCPP_PROFILE_RECORD(allocVector)
+
int *v = INTEGER(res) ;
- for( int i=0; i<n; i++) v[i] = get_index( vec[i] ) ;
+
+ RCPP_PROFILE_TIC
+
+ for( int i=0; i<n; i++) v[i] = get_index( vec[i] ) ;
+
+ RCPP_PROFILE_TOC
+ RCPP_PROFILE_RECORD(lookup)
+
return res ;
}
+ SEXP get_profile_data(){
+ #ifdef HASH_PROFILE
+ return wrap( profile_data ) ;
+ #else
+ return R_NilValue ;
+ #endif
+ }
+
+
bool add_value(int i){
RCPP_DEBUG_2( "%s::add_value(%d)", DEMANGLE(IndexHash), i )
STORAGE val = src[i++] ;
@@ -112,7 +177,7 @@
}
/* NOTE: we are returning a 1-based index ! */
- int get_index(STORAGE value) const {
+ inline int get_index(STORAGE value) const {
int addr = get_addr(value) ;
while (data[addr]) {
if (src[data[addr] - 1] == value)
Modified: pkg/Rcpp/src/cache.cpp
===================================================================
--- pkg/Rcpp/src/cache.cpp 2012-12-05 17:41:52 UTC (rev 4082)
+++ pkg/Rcpp/src/cache.cpp 2012-12-05 18:00:12 UTC (rev 4083)
@@ -19,11 +19,22 @@
// You should have received a copy of the GNU General Public License
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
-#include <Rcpp.h>
+#define USE_RINTERNALS 1
+#include <Rinternals.h>
+#include <Rcpp/routines.h>
+#include <Rcpp/cache.h>
+#include <algorithm>
static bool Rcpp_cache_know = false ;
static SEXP Rcpp_cache = R_NilValue ;
+#define RCPP_HASH_CACHE_INDEX 4
+#define RCPP_CACHE_SIZE 5
+
+#ifndef RCPP_HASH_CACHE_INITIAL_SIZE
+#define RCPP_HASH_CACHE_INITIAL_SIZE 1024
+#endif
+
SEXP reset_current_error__(SEXP) ;
namespace Rcpp {
@@ -37,6 +48,7 @@
// only used for debugging
SEXP get_rcpp_cache() {
if( ! Rcpp_cache_know ){
+
SEXP getNamespaceSym = Rf_install("getNamespace"); // cannot be gc()'ed once in symbol table
SEXP RCPP = PROTECT( Rf_eval(Rf_lang2( getNamespaceSym, Rf_mkString("Rcpp") ), R_GlobalEnv) ) ;
@@ -50,11 +62,12 @@
SEXP init_Rcpp_cache(){
SEXP getNamespaceSym = Rf_install("getNamespace"); // cannot be gc()'ed once in symbol table
SEXP RCPP = PROTECT( Rf_eval(Rf_lang2( getNamespaceSym, Rf_mkString("Rcpp") ), R_GlobalEnv) ) ;
- SEXP cache = PROTECT( Rf_allocVector( VECSXP, 10 ) );
+ SEXP cache = PROTECT( Rf_allocVector( VECSXP, RCPP_CACHE_SIZE ) );
// the Rcpp namespace
SET_VECTOR_ELT( cache, 0, RCPP ) ;
reset_current_error__(cache) ;
+ SET_VECTOR_ELT( cache, RCPP_HASH_CACHE_INDEX, Rf_allocVector(INTSXP, RCPP_HASH_CACHE_INITIAL_SIZE) ) ;
Rf_defineVar( Rf_install(".rcpp_cache"), cache, RCPP );
@@ -116,3 +129,17 @@
return VECTOR_ELT( get_rcpp_cache(), 3 ) ;
}
+int* get_cache( int m){
+ SEXP cache = get_rcpp_cache() ;
+ SEXP hash_cache = VECTOR_ELT( cache, RCPP_HASH_CACHE_INDEX) ;
+ int n = Rf_length(hash_cache) ;
+ if( m > n ){
+ hash_cache = PROTECT( Rf_allocVector( INTSXP, m) ) ;
+ SET_VECTOR_ELT(cache,RCPP_HASH_CACHE_INDEX, hash_cache);
+ UNPROTECT(1) ;
+ }
+ int *res = INTEGER(hash_cache) ;
+ std::fill(res, res+m, 0 ) ;
+ return res ;
+}
+
More information about the Rcpp-commits
mailing list