将原始字节数组复制到空字节向量的最有效方法

时间:2016-01-01 00:53:08

标签: c++ vector stl

我有一个场景,我需要将原始动态分配的uint8_t数组的内容复制到一个向量中(无论何时发生这种情况,都保证为空)。< / p>

vector<uint8_t> myVector;
const uint8_t* myRawArray;

对我来说,复制操作尽可能高效且可移植(可能会使用各种编译器版本)非常重要。

我想到的一种方法是:

myVector.reserve(byteCount);
myVector.insert(myVector.begin(), myRawArray, myRawArray + byteCount);

关于速度如何与此相比的任何想法:

myVector.resize(byteCount);
memcpy(myVector.data(), myRawArray, byteCount);

我猜memcpy应该很快,但后来我被迫使用resize,这需要将内存清零,所以我猜它会减慢它的速度......

另外,还有其他建议吗?

3 个答案:

答案 0 :(得分:8)

如果在复制发生之前不需要创建向量,则可以始终将原始数组传递给向量的构造函数:

std::vector<uint8_t> myVector(myRawArray, myRawArray + byteCount);

如果您确实需要预先构建向量,则以下是一个选项:

std::vector<uint8_t> myVector;
// ... do some stuff ...
// Now, we're ready for the copy, and byteCount is known.
myVector.reserve(byteCount);
std::copy(myRawArray, myRawArray + byteCount, std::back_inserter(myVector));

我建议使用std :: copy,除非事实证明memcpy更快。 std :: copy在C ++代码中更安全,更惯用,但如果真的被证明更快,不要害怕使用memcpy。速度差异很可能会随着不同的编译器而改变。

我希望这会有所帮助。

答案 1 :(得分:1)

memcpy()通常是在汇编中编写的,并且它已经过优化,因此您应该知道memcpy会很快。 vector::insert通常被实现为在引擎盖下调用memcpy,但它确实需要检查向量中是否有足够的空间来进行插入而不进行任何重新分配。我没有对此进行分析,但我打赌第一个调用reserve的版本更快。

替代方法是使用std::copy,在某些情况下使用memcpy比使用memcpy略快,您可以确定如果可能,它也会调用{{ 1}}或做得更好。所以性能问题应该不是问题。它还会考虑增加矢量的大小以符合您的要求。

答案 2 :(得分:0)

感谢您对我的问题的投入,我通过对结构进行以下更改并像这样实现它来解决了问题

   struct YUV_Buffer
   {
void *pCacheBuf = nullptr;
int frameID = 0;
int height = 0;
int width = 0;
void CopyBuf(BYTE * pBuf, int sizBuf)
{
    pCacheBuf = new BYTE[sizBuf];
    memcpy(pCacheBuf, pBuf, sizBuf);
}

YUV_Buffer(BYTE * pBuf, int nFrameID, int nHeight, int nWidth)
    : frameID(nFrameID), height(nHeight), width(nWidth)
{
    CopyBuf(pBuf, 8 * 1024 * 1024);
}

YUV_Buffer(const YUV_Buffer & yuvbuf)
    :frameID(yuvbuf.frameID), height(yuvbuf.height), width(yuvbuf.width)
{
    CopyBuf((BYTE*)yuvbuf.pCacheBuf, 8 * 1024 * 1024);
}
~YUV_Buffer() {
    delete[]pCacheBuf;
    pCacheBuf = NULL;
}
 };

然后我像这样实现它:

  YUV_Buffer nBuffer = YUV_Buffer((BYTE*)pSysFrame, pmfxInSurface->Data.FrameOrder, pmfxInSurface->Info.CropH, pmfxInSurface->Info.CropW);
mBuffer.emplace_back(nBuffer);

希望这可以帮助其他人补充专家交流,以帮助他们获得帮助和投入。

问候 奈杰尔