我大力提倡尽可能使用C++标准库。现代库实现是快速和稳定今天,他们易于使用,有清晰的接口,具有统一的语义。情况并非总是如此,但过去几年来一直如此。在这里,我将查看C++中类似数组的集合,特别是 std::array 和 std:vector 类型。
这两种类型都以类似的方式与各种标准库算法集成。第一种是纯粹的静态的;第二种是静态的。然而,而第二个是动态的。今天,我们将特别看静态性能。
您可能还喜欢: Arrays.hashCode() Vs. 对象.哈希()
首先,让我们来看看整体可用性。坦率地说,由于 STL 对传统 C 类型具有大量支持,它们都工作得很好:
1px;”*用于(康斯特自动& i : std_numbers)
{
st::cout<<<std::endl;
}
(康斯特汽车和ia_numbers)
{
st::cout<<<std::endl;
1px;”•自动最小值 = std:min_element(std_numbers。开始(),std_numbers。结束();
st::cout<<"std最小值"<<<std::endl;
min=std:min_element(std:开始(a_numbers:结束(a_numbers));
std::cout<<"amin"<<=最小<<std::endl;
此处仅存在细微差异,尤其是在调用算法时(即 std::min_element(.))。std::array 类型具有对迭代器的集成支持;我们需要使用来自 STL 的适配器函数从数组生成迭代器
还有一个不是。
您可以使用括号表示法或通过 std:array:at(.) 方法访问 std::array 中的数据:
xxxxxxxxx
std_numbers=0=100;
1px;”>{
st::cout<<<std::endl;
}
std_numbers.在(0=1000;
(康斯特汽车和我std_numbers)
{
1px;”>}
a_numbers=0=100;
(康斯特汽车和ia_numbers)
{
st::cout<<<std::endl;
}
Std::array::at(括号表示法没有,本机数组也是如此。这是件大事!阵列中的超出边界错误是软件中重大、可利用的安全漏洞的主要来源。您可以使用 std:array::at(.)来避免这些问题。这本身就是使用 std::array 的理由。
性能如何?
让我们看一下几个特定的操作 – 创建、分配、检索和复制。下面是我们将使用的代码:
xxxxxxxxx
1px;”•空evaluation_engine(康斯特 T& f, const st::字符串和标签 = “容器”)
{
std::矢量<双>样品;
(自动i=0i<sample_max=i)
{
康斯特汽车start_time=std::chrono::high_resolution_clock::现在();
1px;”> {
f();
}
康斯特自动stop_time=std::chrono::high_resolution_clock::现在();
康斯特自动持续时间=stop_timestart_time;
样品。push_back(持续时间)。计数()
}
1px;”>}
sample_max为 100,loop_max为 1000。此函数采用lambda 表达式或函数,并计算它,计时访问。print_statistics()将计算一些统计数据并打印出来(省略)。
我们的创建测试非常简单:
xxxxxxxxx
1px;”>{
constexprstd::array<int5>数字=01234=;
"STL 创建";
evaluation_engine(*()
{
constexprint数字= = =01234=;
"阵列";
这为我们提供了:
2845
阵列的统计信息
最低: 1830;最大: 1910;平均: 1862.86;std: 27.3357″ 数据朗 = “文本/普通”*
xxxxxxxxx
STL创建的统计信息
最低1787最大1859均1824.66标准27.2845
1px;”•阵列的统计信息
最低1830最大1910均1862.86标准27.3357
基于STL的创建等效于本机数组创建。在这里,它似乎稍微快一些,但这可能是运行这些测试时计算机状态的一个伪影。访问怎么办?首先,让我们看一下数组访问:
xxxxxxxxx
1px;”•evaluation_engine(*和a_numbers= ()
{
康斯特自动值=a_numbers=3*;
"阵列访问";
给美国这些结果:
xxxxxxxxxx
1px;”•阵列访问的统计信息
最小2147最大2241均2160.32std11.3568
现在::数组:
xxxxxxxxxx
2px;高度:22.4px;”>
evaluation_engine(*和std_numbers*()
{
康斯特自动值=std_numbers=3*;
"STL 访问";
xxxxxxxxx
1px;”• STL 访问的统计信息
最低3629最大3998均值3760.79标准121.434
使用 std:array::at(.)
xxxxxxxxx
1px;”• STL 的统计信息()访问
最低4320最大5094均4684.56标准242.694
现在查看 std::array 访问:
xxxxxxxxx
1px;”•evaluation_engine(*和std_numbers*()
{
康斯特自动值=std_numbers。在(3);
"STL 在 () 访问");
现在,我在这些测量中使用高分辨率时钟,我对挂钟时间不感兴趣。不过,我对比较性能感兴趣。根据这些测量值,我们可以看到本机数组访问比 std::array 访问慢 40% 以上。Std:array::at(.)访问比该访问慢 20%。
在我的系统上,这些措施是纳秒的,所以这仍然相当快。然而,std::array 的使用不是免费的。
任务呢?
xxxxxxxxx
1px;”•数组分配的统计信息
最低2057最大2775均2205.31std81.6836
STL分配的统计信息
最低3323最大3556均值3403.62标准28.7593
1px;”*最低: 3640;最高: 3882;均值: 3705.12;Std: 42.9675
同样,有点范围,与std:array::at(.)是最慢的。让我们来看看复制:
xxxxxxxxx
1px;”*最低: 2091;最大: 2156;均值: 2102.45;Std: 11.4301
STL副本的统计信息
最小2608最大值2729均值2626.83std17.4178
显然,除了初始创建之外的所有情况下,本机数组的性能都比 std::array 类型更出色。请记住,在每种情况下,我执行 100,000 个操作,我们讨论的是本机数组和 std::array 时间之间两毫秒内的头发差异。
使用哪个?嗯,我建议你在几乎所有情况下都使用std:array——至少,总是从它开始。在某些情况下,您可能需要过渡到本机阵列,但坦率地说,您通常可以通过算法改进来挤压更多的性能,而不是更改使用的数据结构。