std :: vector :: insert vs std :: list :: operator []

时间:2016-08-05 15:32:05

标签: c++ list vector

我知道std::list::operator[]没有实现,因为它的性能不佳。但是std::vector::insertstd::list::operator[]的效率低得多<?php // API access key from Google API's Console define( 'API_ACCESS_KEY', 'xx' ); $registrationIds = 'xx'; // prep the bundle $msg = array ( 'message' => 'here is a message. message', 'title' => 'This is a title. title', 'subtitle' => 'This is a subtitle. subtitle', 'tickerText' => 'Ticker text here...Ticker text here...Ticker text here', 'vibrate' => 1, 'sound' => 1, 'largeIcon' => 'large_icon', 'smallIcon' => 'small_icon' ); $fields = array ( 'registration_ids' => array($registrationIds), 'data' => $msg ); $headers = array ( 'Authorization: key=' . API_ACCESS_KEY, 'Content-Type: application/json' ); $ch = curl_init(); curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' ); curl_setopt( $ch,CURLOPT_POST, true ); curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers ); curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false ); curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) ); $result = curl_exec($ch ); curl_close( $ch ); echo $result; ?> 。背后有什么解释?

4 个答案:

答案 0 :(得分:9)

std::vector::insert已实施,因为std::vector必须满足SequenceContainer concept的要求,而operator[]不是任何概念(我知道)所必需的,可能是在c ++ 17中添加ContiguousContainer概念。因此operator[]添加到可以像数组一样使用的容器,而接口规范需要insert,因此符合某些概念的容器可以用于通用算法。

答案 1 :(得分:2)

我认为斯拉瓦的答案做得最好,但我想提供补充说明。通常使用数据结构,访问比插入更常见,反之亦然。有许多数据结构可能试图以插入为代价来优化访问,但反向更为罕见,因为它在现实生活中往往不太有用。

operator[],如果为链接列表实现,则可能会访问现有值(类似于vector的方式)。 insert添加了新值。如果随后的访问速度非常快,那么您很可能愿意将一些新元素插入到vector中。在许多情况下,元素插入可以完全在关键路径之外,而关键路径由单个遍历或已经存在的数据的随机访问组成。因此,在这种情况下让insert为您处理细节非常方便(实际上有效且正确地编写它实际上有点烦人)。这实际上是一个非常罕见的矢量使用。

另一方面,在链表上使用operator[]几乎总是表明您使用了错误的数据结构。

答案 2 :(得分:1)

std::list::operator[]需要进行O(N)遍历,并不真正符合list的设计要求。如果您需要operator[],请使用其他容器类型。当C ++民众看到[]时,他们假设是O(1)(或者更糟糕的是,O(Log N))操作。为[]提供list会打破这一点。

但是虽然std::vector::insert 也是 O(N),但可以进行优化:通过{{{}可以轻松优化端点插入1}}的容量在大块中增长。中间插入需要逐个元素移动,但在现代芯片组上也可以非常快速地执行。

答案 3 :(得分:0)

[]运算符继承自普通数组。它一直被理解为底层容器的快速(子线性时间)访问器。由于list不支持子线性时间访问,因此实现运算符没有意义。

auto a = Container [10]; // Ideally I can assume this is quick

std::list <>::operator []的等效内容为std::next <std::list<>::iterator>。记录在cpp-reference

auto a = *std::next (Container.begin (), 10); // This may take a little while

这是索引容器的真正通用方式。如果容器支持随机访问,则它将是恒定时间,否则它将是线性的。