memcpy如下所示使用它是否更好,或者std::copy()在性能方面更好用?为什么?
char *bits = NULL;
...
bits = new (std::nothrow) char[((int *) copyMe->bits)[0]];
if (bits == NULL)
{
cout << "ERROR Not enough memory.\n";
exit(1);
}
memcpy (bits, copyMe->bits, ((int *) copyMe->bits)[0]);
Run Code Online (Sandbox Code Playgroud) 我正在将C应用程序移植到C#中.C应用程序从第三方DLL调用许多函数,所以我在C#中为这些函数编写了P/Invoke包装器.其中的一些C函数分配,我有在C#应用程序使用的数据,所以就用IntPtr的,Marshal.PtrToStructure并且Marshal.Copy到本机数据(数组和结构)复制到管理变量.
不幸的是,C#app被证明比C版慢得多.快速的性能分析表明,上述基于编组的数据复制是瓶颈.我正在考虑通过重写它以使用指针来加速C#代码.由于我没有C#中不安全的代码和指针的经验,我需要有关以下问题的专家意见:
unsafe代码和指针而不是IntPtr和Marshaling有什么缺点?例如,它是否以任何方式更不安全(双关语)?人们似乎更喜欢编组,但我不知道为什么.为了使情况更加清晰,我将一个小的示例代码(实际代码复杂得多)整合在一起.我希望这个例子说明我在谈论"不安全的代码和指针"与"IntPtr和Marshal"时的意思.
MyLib.h
#ifndef _MY_LIB_H_
#define _MY_LIB_H_
struct MyData
{
int length;
unsigned char* bytes;
};
__declspec(dllexport) void CreateMyData(struct MyData** myData, int length);
__declspec(dllexport) void DestroyMyData(struct MyData* myData);
#endif // _MY_LIB_H_
Run Code Online (Sandbox Code Playgroud)
MyLib.c
#include <stdlib.h>
#include "MyLib.h"
void CreateMyData(struct MyData** myData, int length)
{
int i;
*myData = (struct MyData*)malloc(sizeof(struct MyData));
if (*myData != NULL)
{
(*myData)->length = length; …Run Code Online (Sandbox Code Playgroud) 我有一个foo(int[] nums)我理解的功能基本上相当于foo(int* nums).在里面foo我需要将指向的数组的内容复制nums到一些int[10]声明的范围内foo.我理解以下内容无效:
void foo (int[] nums)
{
myGlobalArray = *nums
}
Run Code Online (Sandbox Code Playgroud)
复制数组的正确方法是什么?我应该像这样使用memcpy:
void foo (int[] nums)
{
memcpy(&myGlobalArray, nums, 10);
}
Run Code Online (Sandbox Code Playgroud)
或者我应该使用for循环?
void foo(int[] nums)
{
for(int i =0; i < 10; i++)
{
myGlobalArray[i] = nums[i];
}
}
Run Code Online (Sandbox Code Playgroud)
我缺少第三种选择吗?
是memcpy()通常速度比strcpy()(上最真实的平台)?(我假设字符串的大小是已知的.)
如果我正确地记得i386汇编程序,则会有loop指令复制给定数量的字节或单词.所以它是最快的方式,而strcpy()i386汇编程序实现将'\0'在一个简单的循环中使用手动检查.
所以我觉得在x86上memcpy()要快于strcpy().
其他架构是什么?
这是基本的,但我的谷歌搜索只是没有削减它.我知道我必须做一些其他事情来逐个移动数组的值,但是下面的编码给了我相同的项[k]到项目[infinity]的值,等于项目[k].我不明白的是,当我将k值复制到k + 1槽时,如何保留原始k + 1值.
if ( i < numItems) //if i is inside the used boundaries of the array
{
for (int k = i; k < numItems; k++) //shift the array values from point i
{
double temp = 0.0;
temp = items[k];
items[k+1] = temp;
}
items[i] = value; //and insert value into i
}
Run Code Online (Sandbox Code Playgroud)
它必须是递归方法吗?
如何使用标准图像处理过滤器(来自OpenCV)从图像中删除长水平和垂直线?
图像是B&W,因此删除意味着简单地绘制黑色.
插图:

我目前正在使用Python,迭代像素行和列并检测连续像素的范围,删除那些长于N像素的像素.但是,与OpenCV库相比,它确实很慢,如果有一种方法可以实现与OpenCV功能相同的功能,那么可能会快几个数量级.
我想这可以通过使用一行像素(对于水平线)的内核进行卷积来完成,但是我很难确定完成这一操作的确切操作.
在查看x86/x64架构中的寄存器表之后,我注意到有128,256和512位寄存器的整个部分,我从未见过它们用于汇编或反编译的C/C++代码: XMM(0-15)表示128,YMM(0-15)表示256,ZMM(0-31)512.
做了一些挖后我所收集的是,你必须使用2个64位操作,以一个128位的数字进行的,而不是使用通用的数学,add,sub,mul,div操作.如果是这种情况,那么具有这些扩展寄存器集的用途究竟是什么,是否有任何汇编操作可以用来操作它们?
所以在我正在做的每次迭代结束时,我想让我的数组等于我的新数组(我称之为array_new).我希望数组的每个元素都采用与array_new相同的值,但我有兴趣尽可能快地获取代码,因此在当前代码执行的情况下,逐个元素地复制所有元素不是一个选项:
for(i=0;i<N_a;i++) {
for(j=0;j<N_b;j++) {
array[i][j] = array_new[i][j];
}
}
Run Code Online (Sandbox Code Playgroud)
这需要相当长的时间,因为我的N_a和N_b的值非常大.有没有办法简单地改变每个指向的内容,以便我可以更快地开始下一次迭代?我尝试过这样的事情
double *temp = *array;
*array = *array_new;
*array_new = temp;
Run Code Online (Sandbox Code Playgroud)
为了尝试避免缓慢的逐个元素复制过程,但它似乎不适合我.实际上,我正在努力实现的是,数组的每个元素都指向array_new中的相应元素,但我无法弄清楚如何使指针执行此操作.
任何帮助将非常感激!
让我们假设我调用第三方 API 并返回一个可变的 N 多对象列表。该列表可以小到 10 个对象,也可以大到几千个。然后我总是想在返回的列表的索引 0 处插入一个对象。我知道我可以轻松地在索引 0 处调用 add ,但这将是 O(n),因为它会为插入移动每个对象。我的问题是,使用我计划在开始时插入的项目创建一个新列表,然后在返回的第 3 方 N 多列表中调用该新列表上的 addAll 平均会更快(处理明智)吗?