[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