insert与copy的插入比较

标签: stl vector
97人阅读 评论(0) 收藏 举报
分类:

举例代码:
将一段数据复制到vector的首部

int data[5] = {0,1,2,3,4};
vector<int> vInt;
vInt.push_back(10);
vInt.insert(vInt.begin(),data,data+5);

vInt.clear();
vInt.push_back(10);
copy(data, data+5, inserter(vInt,vInt.begin()));

查看copy方法的实现:

template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, 
              OutputIt d_first)
{
    while (first != last) {
        *d_first++ = *first++;
    }
    return d_first;
}

copy的第三个参数inserter是这样的:

template< class Container >
std::insert_iterator<Container> inserter( Container& c, typename Container::iterator i )
{
    return std::insert_iterator<Container>(c, i);
}

insert_iterator的实现是这样的:

_LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
        : container(_VSTD::addressof(__x)), iter(__i) {}

对,其实就是构造了一个容器。
insert_iterator是一个类,不同的容器以模板泛型编程的方式被类实现。copy每调用一次inserter(d_first)即申请内存创建对象,随即进行数据复制(*d_first++ = *first++)

insert方法中相关的底层函数调用

vector::__move_range ==> std::move_backward ==> std::move
move_range:

template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to)
{
    pointer __old_last = this->__end_;
    difference_type __n = __old_last - __to;
    for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)
        __alloc_traits::construct(this->__alloc(),
                                  _VSTD::__to_raw_pointer(this->__end_),
                                  _VSTD::move(*__i));
    _VSTD::move_backward(__from_s, __from_s + __n, __old_last);
}

在循环中申请了一段区间内存,然后一次性move_backward.
move_backward

template< class BidirIt1, class BidirIt2 >
BidirIt2 move_backward(BidirIt1 first,
                                    BidirIt1 last,
                                    BidirIt2 d_last)
{
    while (first != last) {
        *(--d_last) = std::move(*(--last));
    }
    return d_last;
}

std::move的实现其实很简单:

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
const _Tp&
move(const _Tp& __t)
{
    return __t;
}

故,从效果上来看,copy需要多次调用inserter函数,申请一段内存,每一次申请成功就复制数据;区间型insert这是在一个循环中申请够内存后再通过move_backward以逆向的方式一次性复制数据。此外,copy每次调用inserter都会发生移动,而insert因为是申请区间内存,故仅发生一次大的移动。
故从效率上看insert更好。

查看评论

vertica从其他表迁移数据到新表(insert into 语句用法实例)

vertica从本地其他表迁移数据到新表(insert into 语句用法实例)
  • tx18
  • tx18
  • 2014-05-22 15:06:09
  • 1357

postgresql copy的使用一例

CREATE OR REPLACE FUNCTION dbo.gps_write_files()   RETURNS trigger AS $BODY$ declare dir varcha...
  • weixin_36707770
  • weixin_36707770
  • 2017-04-16 15:07:09
  • 567

android中SQLite数据库中用insert同时插入多条记录的方法和效率比较

  • 2013年12月11日 14:37
  • 20KB
  • 下载

数据库重构工具 LiquiBase(3 插入记录)

插入记录有两种方式。一、csv
  • WANTAWAY314
  • WANTAWAY314
  • 2016-11-22 14:44:59
  • 28149

Python中列表的append操作比insert操作效率高的实质

Python中的列表并不是传统意义上的列表,这也是Python中列表的append操作比insert操作高效的根本原因。...
  • xiong452980729
  • xiong452980729
  • 2016-01-21 13:51:15
  • 2983

Insert语句加/*+APPEND */在循环中单条提交对系统的影响分析

Insert语句加/*+APPEND*/ hint在循环中单条提交,由于/*+APPEND */ hint是在高水位线以上插入的特性,导致每提交一次,就会取一个新的block存放,高水位就上推一个bl...
  • ljunjie82
  • ljunjie82
  • 2015-01-17 10:30:56
  • 1926

insert /*+append*/和各种insert插入速度比较

SQL> select count(*) from t; COUNT(*) ---------- 5442048 **************************** SQL> alte...
  • weiliu1463
  • weiliu1463
  • 2013-05-31 19:21:42
  • 421

【随笔】postgresql导出sql插入语句

Postgresql由于其免费及轻量级,经常性的使用它。平时对数据库的备份,直接使用其对应的备份工具备份并导入即可完成。 但,有时会需要使用其进行导出类似insert的语句,来完成对其他数据库的导入...
  • wenxuechaozhe
  • wenxuechaozhe
  • 2017-04-04 17:07:11
  • 860

关于Access Insert Into 语句的时间插入问题?

Insert Into [News] ([time]) values ("&Now()&")1.time这个字段是ACCESS的保留字,所以要用中括号包含起来.2.在ACCESS里,时间也是个特殊的字...
  • quweiie
  • quweiie
  • 2007-12-15 08:40:00
  • 5239

一条insert语句批量插入多条记录

常见的insert语句,向数据库中,一条语句只能插入一条数据: -- 一条insert只能插入一条数据 insert into person (id, personCode, personName...
  • Mokily
  • Mokily
  • 2015-01-30 13:59:01
  • 10627
    个人资料
    持之以恒
    等级:
    访问量: 37万+
    积分: 9441
    排名: 2419
    我的链接
    最新评论