关闭

insert与copy的插入比较

标签: stlvector
60人阅读 评论(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更好。

0
0
查看评论

MERGE 比 DELETE INSERT 更新 可靠多了

MERGE 比  DELETE INSERT 慢很多! 可 DELETE INSERT 总是 发生违反唯一关键子,删除了无法再插进去。还有时不时的丢失数据。 MERGE 可以减少数据量来提高运行速度,减少 WHEN MATCHED THEN  UPDATE 字段来 少生...
  • ZengMuAnSha
  • ZengMuAnSha
  • 2010-05-13 14:04
  • 1204

Postgresql单表插入百万数据

说到插入数据,一开始就想到: insert int A values(*******************) 插入多条数据,最多想到: 1.prepare,然后再bind参数,最后一次性插入多条 2.写成这样: insert into A values(**********),(*********...
  • rongyongfeikai2
  • rongyongfeikai2
  • 2014-01-07 00:06
  • 5203

Mybatis 使用<if test/>实现选择插入

最近遇到需要需要根据 areaId的范围进行插入,在使用中使用when test实现数据范围选择,之前在test中使用 大于号 > 是没有问题的,例如<when test="praise > 0">于是根据编程的想法,就写了这个<if test=&q...
  • WSRspirit
  • WSRspirit
  • 2016-03-11 17:04
  • 5623

insert 插入数据

语法格式: insert into 表名称[(字段名称1,字段名称2……)]values[(值1,值2,……)];标准语法:对于没有数据的列就不写进字段列表;简略语法:如果插入时没有明确的写出字段,则没有值得字段用null来代替;两种写法比较:推荐使用标准写法,不推荐使用简略写法。简略写法再添加表字...
  • magi1201
  • magi1201
  • 2015-12-06 19:57
  • 859

利用子查询一次性 insert 多条数据

insert into emp_wang(id,name,deptno) select empno,ename,deptno from emp where deptno=10;
  • confirmAname
  • confirmAname
  • 2013-07-22 00:31
  • 982

数据库学习 - insert into(插入数据)

向表中添加数据 Insert into 简单语法形式: Insert into 表名[(列名[,列名]...)] values(值 [,值],...);   Values 后面的值的排列要与into子句后面的列名排列一致; 若表名后面的所有列名省略,则values后的值的排列要...
  • linan_pin
  • linan_pin
  • 2017-04-12 16:16
  • 1291

插入数据库语句比较性能

insert语句,sqldataadapter.update(dataset,tablename);sqlbulkcopy.WriteToServer(datatable);三个方法的性能进行比较: 生成测试的datatable表,表结构如下: UniqueID(主键,自动增长)  |...
  • qq_32733803
  • qq_32733803
  • 2017-12-08 08:48
  • 81

批处理中Copy与Xcopy的区别

###Date: 2017/6/20 ###Author: Soaringlee 1):copy不能在有子目录存在的文件中拷贝文件的同时重命名此文件名(注:这里C:为根目录,bat为子目录),而xcopy能,不过会出现提示,当然你可以加参数而不使它提示  C:\>cop...
  • SoaringLee_fighting
  • SoaringLee_fighting
  • 2017-06-20 10:28
  • 2411

Insert语句与外键冲突

提示错误:  消息 547,级别 16,状态 0,第 2 行 INSERT 语句与 FOREIGN KEY 约束"FK_T_Student_T_CardInfo"冲突。该冲突发生于数据库"SchoolRecharge_sys",表"db...
  • wlccomeon
  • wlccomeon
  • 2013-05-31 16:54
  • 5371

大数据导入之Bulk Insert的一点总结

最近项目中需要对服务程序进行大规模的模拟测试,于是专门写了一个测试程序,测试程序包含:测试数据的管理,功能测试,流程测试,压力测试。     对于要测试的程序的数据源来自数据库,所以,需要模拟一个大的数据量,从1W,10W,100W,1000W...。其实,一直以来没有怎么搞过...
  • rainychan2009
  • rainychan2009
  • 2013-12-13 23:19
  • 1873
    个人资料
    • 访问:355947次
    • 积分:9155
    • 等级:
    • 排名:第2424名
    • 原创:578篇
    • 转载:13篇
    • 译文:0篇
    • 评论:36条
    我的链接
    最新评论