对象的动态数组 - 初始化方法之间的区别
Dynamic array of objects - difference between initialisation methods
我需要在一个函数中创建一个节点对象的动态数组,该函数执行一些我不会深入研究的逻辑。
对于不同数量的节点(节点数递增,直到超过一百万个节点),将多次连续调用此函数。
起初我按以下方式初始化数组:
node** heaps = new node*[arraySize];
for (int i=0; i < arraySize; i++)
heaps[i] = nullptr;
但是,由于这个函数被调用了很多次,for循环会拖慢我的程序(我需要函数按照logn的顺序,但是这个for循环在开始的时候已经使它在n的顺序)。
然后我看到了另一种初始化动态数组的方法,如下所示:
node** heaps = new node*[arraySize]();
我的程序似乎只用上面一行就可以工作,但是,我不太确定这两种方法之间的区别是什么,以及它是否真的提高了性能(因为我无法确定一个很大的性能差异)。
谁能解释一下?
使用()
将默认初始化值初始化数组。循环对性能的好处微乎其微,因为它做同样的工作。但是,如果性能因此受到影响,那么您将不得不查看 code/algorithm 中的其他地方,看看是否有任何内容可以移至 不太温暖的代码路径 .
如果您必须使用动态数组,如果您在编译时知道 N
,请使用 std::vector<node*>
或 std::array<node*,N>
。
或者更好的是,使用现代 C++ 工具:
using node_ptr = std::unique_ptr<node>;
std::vector<node_ptr> heaps;
您询问的额外“()”称为初始值设定项。它是可选的,除非您提供的类型是自动的,在这种情况下,类型将从您提供的初始化程序中推导出来。
在您的第一个示例中,您的节点指针是默认初始化的,这意味着它们的值是不确定的。他们可以指着任何东西。
在你的第二个例子中,你的节点指针是值初始化的,这意味着它们都是空指针。
两种方式的最终结果都是一样的。第二个示例依赖于您的实现来为您提供零初始化的指针,但如果它不如您的 for 循环那么快或更快,我会感到惊讶。说到性能,一定要衡量。
我需要在一个函数中创建一个节点对象的动态数组,该函数执行一些我不会深入研究的逻辑。 对于不同数量的节点(节点数递增,直到超过一百万个节点),将多次连续调用此函数。
起初我按以下方式初始化数组:
node** heaps = new node*[arraySize];
for (int i=0; i < arraySize; i++)
heaps[i] = nullptr;
但是,由于这个函数被调用了很多次,for循环会拖慢我的程序(我需要函数按照logn的顺序,但是这个for循环在开始的时候已经使它在n的顺序)。
然后我看到了另一种初始化动态数组的方法,如下所示:
node** heaps = new node*[arraySize]();
我的程序似乎只用上面一行就可以工作,但是,我不太确定这两种方法之间的区别是什么,以及它是否真的提高了性能(因为我无法确定一个很大的性能差异)。
谁能解释一下?
使用()
将默认初始化值初始化数组。循环对性能的好处微乎其微,因为它做同样的工作。但是,如果性能因此受到影响,那么您将不得不查看 code/algorithm 中的其他地方,看看是否有任何内容可以移至 不太温暖的代码路径 .
如果您必须使用动态数组,如果您在编译时知道 N
,请使用 std::vector<node*>
或 std::array<node*,N>
。
或者更好的是,使用现代 C++ 工具:
using node_ptr = std::unique_ptr<node>;
std::vector<node_ptr> heaps;
您询问的额外“()”称为初始值设定项。它是可选的,除非您提供的类型是自动的,在这种情况下,类型将从您提供的初始化程序中推导出来。
在您的第一个示例中,您的节点指针是默认初始化的,这意味着它们的值是不确定的。他们可以指着任何东西。
在你的第二个例子中,你的节点指针是值初始化的,这意味着它们都是空指针。
两种方式的最终结果都是一样的。第二个示例依赖于您的实现来为您提供零初始化的指针,但如果它不如您的 for 循环那么快或更快,我会感到惊讶。说到性能,一定要衡量。