I have enermous array:
int* arr = new int[BIGNUMBER];
How to fullfil it with 1 number really fast. Normally I would do
for(int i = 0; i < BIGNUMBER; i++)
arr[i] = 1
but I think it would take long.
Can I use memcpy
or similar?
I have enermous array:
int* arr = new int[BIGNUMBER];
How to fullfil it with 1 number really fast. Normally I would do
for(int i = 0; i < BIGNUMBER; i++)
arr[i] = 1
but I think it would take long.
Can I use memcpy
or similar?
您可以尝试使用标准功能std::uninitialized_fill_n
:
#include <memory>
// ...
std::uninitialized_fill_n(arr, BIGNUMBER, 1);
无论如何,在性能方面,规则是始终进行测量以支持您的假设——尤其是如果您因为所谓的性能改进而放弃一个清晰、简单的设计而采用更复杂的设计时。
编辑:
请注意,正如 Benjamin Lindley 在评论中提到的那样,对于琐碎的类型std::uninitialized_fill_n
并没有比更明显的类型带来任何优势std::fill_n
。非平凡类型的优势将存在,因为std::uninitialized_fill
它允许您分配内存区域,然后在适当的位置构造对象。
但是,不应陷入调用未初始化std::uninitialized_fill_n
的内存区域的陷阱。例如,以下将给出未定义的行为:
my_object* v = new my_object[BIGNUMBER];
std::uninitialized_fill_n(my_object, BIGNUMBER, my_object(42)); // UB!
动态数组的替代方法是std::vector<int>
使用接受每个元素的初始值的构造函数:
std::vector<int> v(BIGNUMBER, 1); // 'BIGNUMBER' elements, all with value 1.
如前所述,需要衡量绩效。这种方法提供了额外的好处,即内存将被自动释放。
Andy Prowl 解决方案的一些可能替代std::uninitialized_fill_n()
方案,仅供后代使用:
memset
就可以了。memsetw
,但并非无处不在。最后但同样重要的是,回应一些评论者:你应该测试并看看。编译器往往非常擅长识别和优化这样的模式——您可能只是在使用除简单循环或uninitialized_fill_n
.
您可能对之前的问题感兴趣:
在启用优化的 Linux/x86 gcc 下,您的代码将编译为以下内容:
rax = arr
rdi = BIGNUMBER
400690: c7 04 90 01 00 00 00 movl $0x1,(%rax,%rdx,4)
立即移动int(1)
到 rax + rdx
400697: 48 83 c2 01 add $0x1,%rdx
递增寄存器 rdx
40069b: 48 39 fa cmp %rdi,%rdx
Cmp rdi 到 rdx
40069e: 75 f0 jne 400690 <main+0xa0>
如果已达到 BIGNUMBER,则跳回开始。
在我的机器上每 GB 大约需要 1 秒,但我敢打赌,其中大部分是在物理内存中分页以支持未初始化的分配。
只需将循环展开 8 或 16 次。像这样的函数memcpy
很快,但它们确实是为了方便,而不是比你可能写的任何东西都要快:
for (i = 0; i < BIGNUMBER-8; i += 8){
a[i+0] = 1; // this gets rid of the test against BIGNUMBER, and the increment, on 7 out of 8 items.
a[i+1] = 1; // the compiler should be able to see that a[i] is being calculated repeatedly here
...
a[i+7] = 1;
}
for (; i < BIGNUMBER; i++) a[i] = 1;
编译器可能会为您展开循环,但为什么要冒险呢?
使用 memset 或 memcpy
memset(arr, 0, BIGNUMER);
memset(arr, 1, sizeof(int) * BIGNUMBER);