Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用向量还是数组?_C++_String_Algorithm_Sorting_Vector - Fatal编程技术网

C++ 使用向量还是数组?

C++ 使用向量还是数组?,c++,string,algorithm,sorting,vector,C++,String,Algorithm,Sorting,Vector,我正在写字符串排序,我无法决定是使用数组还是向量,这样我在算法中使用的交换操作会更快。 假设我有这样一个向量和数组 vector<string> vec; string str[20]; 它们是等价的。事实上,它们不仅是等价的,而且是相同的,因为在每种情况下,您都调用完全相同的函数: basic_string::swap() 但是,在更大的问题上——应该使用数组还是使用向量。作为一个经验法则,我认为我很难找到许多合法的例外情况,除非你有一个特定的原因,否则你应该在C++中默认使用

我正在写字符串排序,我无法决定是使用数组还是向量,这样我在算法中使用的交换操作会更快。 假设我有这样一个向量和数组

vector<string> vec;
string str[20];

它们是等价的。事实上,它们不仅是等价的,而且是相同的,因为在每种情况下,您都调用完全相同的函数:

basic_string::swap()

但是,在更大的问题上——应该使用数组还是使用
向量
。作为一个经验法则,我认为我很难找到许多合法的例外情况,除非你有一个特定的原因,否则你应该在C++中默认使用<代码>向量<代码>。速度不是这些原因之一,除非是在非常罕见的情况下。

访问数组中的元素将具有更好的局部性,因为在访问数组中的元素时,您将对第一个元素的地址应用偏移量。当访问vector中的元素时,您将应用两个偏移量—一个偏移量用于获取存储在vector类中的数组指针,另一个偏移量用于获取该数组中的元素。但这一点都不重要,编译器可能(甚至应该)优化这种不同的方法

从理论上讲,这里可能会减慢您的速度的是字符串比较,以及访问这些字符串的内容。你看,
std::string
在堆上分配它的数据,如果你运气不好,每个字符串的数据都会指向彼此距离太远的内存位置。考虑到字符串的内容无法放入一级缓存以及内存位置的随机性,预取器将无法将数据提供给您的代码,CPU将只是在等待内存总线时卡住


我会从更高级的优化开始。首先,运行一个分析器来查看程序中的瓶颈到底是什么。如果结果是排序,我会看看是否可以使用不同的排序算法(即部分排序而不是完全排序)。然后尝试优化内存访问。然后才考虑是否应该使用std::vector。我认为您在这里所做的是过早的优化,这是不好的。

交换操作的速度应该大致相同,也许数组的速度快得可以忽略不计,但不是交换操作本身,而是通过
向量
访问元素的方式


您可能应该在此处查找与性能无关的标准。

您自己分析和查看如何?两者都不是;您应该使用
std::array
:-)这不取决于实现、操作系统和许多其他因素吗@状态:大多数操作的算法复杂性适用于所有容器。一个
std::vector
相当于一个数组,除了它丰富的界面和安全性!有人可能会争论间接操作之类的问题,但有些操作通常是内联的。最后,最好的测量方法是自己对其进行分析。您根据什么得出阵列可能更快的结论?因为向量可能较慢,因为它在阵列顶部添加了一个非常薄的层。比如做边界检查,等等。但是一旦获得对成员的引用,它是相同的。向量不做边界检查。也就是说,就标准而言。某些特定实现(如MSVC)可能会添加错误和边界检查功能,但这通常只会添加到调试版本中,在发布版本中禁用,甚至可以在调试版本中禁用。谢谢,我不知道是什么让d/v这么做的,我很感谢您的评论,但老实说,我可以没有;-)@Downvoter:如果你不同意我说的话,请解释。不要不同意(因为我完全同意),但偶尔不使用
vector
的一个原因是为了避免初始化问题的顺序。(当然,这只影响具有静态生存期的变量。)如果可以使用带有静态初始值设定项的数组,则不会出现初始化顺序问题。在C++03中,C风格的数组是编译器计算初始值设定项并相应地对数组进行尺寸标注的唯一容器。@James:很好。我会将其归类为“一个不这样做的特殊原因”,但同时我也会将其归类为一种代码气味。但是,在所有情况下:它们都是POD数组(可以静态分配),它们位于名称空间范围(几乎总是未命名的名称空间),它们是
const
。换句话说,它们由编译器进行布局和初始化,并且从未更改。(当然,这意味着,我非常肯定不会有任何内存管理问题或诸如此类的问题。)这是一个有限的、非常特殊的用途,但我不会对它产生怀疑。我想我们在这方面是一致的。我也和你一样,在非常有限的特殊情况下。我提到代码气味的原因是为了给阅读本文的其他人播下种子,如果你有初始化顺序问题,这可能表明代码的设计存在其他缺陷。-1因为:“当通过索引访问元素时,std::vector会检查索引是否超出范围”这是错误的。请看我对@Michael Krelin的回答的评论。@JohnDibling:噢,废话。你是对的-它没有,把这个混蛋和Java的数组搞混了!
basic_string::swap()