0

有没有一种方法可以创建由现有 C char* ptr 支持的 RAWSXP 向量。

下面我展示了需要重新分配和复制字节的当前工作版本,以及不存在的第二个想象版本。

    // My current slow solution that uses lots of memory
    SEXP getData() {
      // has size, and data
      Response resp = expensive_call();
    
      //COPY OVER BYTE BY BYTE
      SEXP respVec = Rf_allocVector(RAWSXP, resp.size);
      Rbyte* ptr = RAW(respVec);
      memcpy(ptr, resp.msg, resp.size);
    
      // free the memory
      free(resp.data);
    
      return respVec;
    }
    
    // My imagined solution
    SEXP getDataFast() {
      // has size, and data
      Response resp = expensive_call();
    
      // reuse the ptr
      SEXP respVec = Rf_allocVectorViaPtr(RAWSXP, resp.data, resp.size);
    
      return respVec;
    }

我还注意到Rf_allocVector3这似乎可以控制向量的内存分配,但我无法让它工作。这是我第一次编写 R 扩展,所以我想我一定是在做一些愚蠢的事情。我试图避免复制,因为数据将在 GB 左右(非常大,虽然稀疏,矩阵)。

4

1 回答 1

0

复制超过 1 GB 的时间小于 1 秒。如果您的通话费用很高,那么您应该分析一下它是否真的是一个瓶颈,这可能是一个边际成本。

您尝试做事的方式可能是不可能的,因为 R 怎么知道如何垃圾收集数据?

但是假设您使用的是 STL 容器,我最近看到的一个巧妙技巧是使用 STL 容器的第二个模板参数——分配器。

template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

该策略的大致轮廓是这样的:

  1. 使用满足所有要求的R-memory 创建自定义分配器(基本上你只需要allocateand deallocate
  2. 每次需要从 STL 容器向 R 返回数据时,请确保使用自定义分配器对其进行初始化
  3. 在返回数据时,提取由 R 内存分配器创建的底层 R 数据——无副本

这种方法为您提供了 STL 容器的所有灵活性,同时仅使用 R 知道的内存。

于 2020-12-25T01:30:24.407 回答