Cherno C++学习笔记 P48 如何让vector运行的更快

这一篇文章当中我们会讲到有关于vector的使用优化问题,如何能够让vector运行得更快。C++优化是一个非常非常复杂的问题,最重要的是要了解环境,要知道事情是如何发生的,以及我们应该怎么做。当然我们今天会做的事情其实只是触及表面。

vector在我们添加新元素的时候,因为内存不够,所以会不断地进行寻找新的足够的内存——把原来的数据全部拷贝到新的内存里面——删除原有的数据这样一个工作,不断分配新内存的过程费时费力,拖慢我们的速度。我们希望可以避免这种事情的发生,也就是第一个要在使用vector的时候优化的部分:avoid copy。

如何查看我们复制了多少次?也很简单,我们直接复制构造函数里面写一句就可以了。所以我们直接写一个这样的Vertex类型如下所示:

struct Vertex {
public:float x, y, z;
public:Vertex(float x, float y, float z):x(x), y(y), z(z){}Vertex(const Vertex& other) {this->x = other.x;this->y = other.y;this->z = other.z;std::cout << "The vertex is copied!" << std::endl;}
};

可以看到我们在它的复制构造函数里面写了一个打印copy信息,这样可以让我们知道总共copy了多少次,然后我们运行如下的main程序:

int main() {std::vector<Vertex>vertices;vertices.push_back({ 1,2,4 });vertices.push_back({ 2,4,5 });vertices.push_back({ 1,4,8 });std::cin.get();
}

可以看到,我们就向这个vertices里面塞了三个元素,然后我们看看输出:

居然被复制粘贴了六次!这可不是我们希望的。

那么到底是哪里发生了这么多次复制粘贴?主要的来源有两个,第一个是如果我们在main当中进行push_back,那么实际上我们做的事情是先在main当中创立一个变量,然后复制粘贴到了我们的vector当中去,这是一个可以优化的点,如果我们可以直接创建在vector里面,是不是就可以省去这样一个步骤了?

第二个是在不停的push_back当中,我们会不停的进行移动与复制操作,同样会调用复制构造函数进行复制。其实我们稍微想一下就会发现,如果我们push_back进去n个元素,那么我们会调用\frac{(n+1)n}{2}次复制构造函数,这个确实是不能接受的。

我们先去解决第二个问题。为了能够不用一直申请新内存,所以最好的方式就是直接把内存申请够,我们直接留出可以存放三个元素的内存空间即可。vector为我们提供了reserve方法来实现这一点:

std::vector<Vertex>vertices;
vertices.reserve(3);
vertices.push_back({ 1,2,4 });
vertices.push_back({ 2,4,5 });
vertices.push_back({ 1,4,8 });

我们这样写就会发现,我们的copy次数从6次减为了3次,我们成功的减少了一半的复制粘贴,因为我们不需要再到处找内存然后复制粘贴过去了,这节约了我们很多时间。

但是需要注意的的一点是,不要直接使用

std::vector<Vertex>vertices(3);

的方式来留够内存,因为这样做的话,其实是会直接构造出三个Vertex对象来,而不是单纯的给我们留出空间。

而为了解决第一个问题,我们需要讲push_back替换为emplace_back且需要直接使用参数列表。

std::vector<Vertex>vertices;
vertices.reserve(3);
vertices.emplace_back(1,2,4);
vertices.emplace_back(2,4,5);
vertices.emplace_back(1,4,8);

这种使用方式意味着我们直接在vertices里面构造了这三个vertex对象,而不是先在main里面构建,再复制到vertices里面去。我们再次运行程序,会发现复制构造函数再也不被调用了,意味着我们成功的规避了所有的copy,提高了我们的vector的表现。

但是这只是很简单和表层的,后面我们需要自己实现自己的vector类,会有更多的需要优化的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/498963.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis执行一条sql语句的流程(源码解析)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MyBatis执行一条sql语句的流程&#xff08;源码解析&#xff09; MyBatis执行sql语句的流程加载配置文件加载配置文件的流程 创建sqlsessionFactory对象解析Mapper创建sqlses…

淺談Cocos2djs逆向

前言 簡單聊一下cocos2djs手遊的逆向&#xff0c;有任何相關想法歡迎和我討論^^ 一些概念 列出一些個人認為比較有用的概念&#xff1a; Cocos遊戲的兩大開發工具分別是CocosCreator和CocosStudio&#xff0c;區別是前者是cocos2djs專用的開發工具&#xff0c;後者則是coco…

吊舱激光测距核心技术详解!

一、核心技术 吊舱激光测距的核心技术主要体现在激光发射与接收、信号处理与距离计算、以及数据校正与优化等方面。 激光发射与接收&#xff1a; 激光发射器&#xff1a;产生经过调制的激光束&#xff0c;该激光束具有特定的频率和波形。这些激光束被投射到目标物体上。 光…

SpringAI从入门到熟练

学习SpringAI的记录情况 文章目录 前言 因公司需要故而学习SpringAI文档&#xff0c;故将自己所见所想写成文章&#xff0c;供大佬们参考 主要是为什么这么写呢&#xff0c;为何不抽出来呢&#xff0c;还是希望可以用的时候更加方便一点&#xff0c;如果大家有需求可以自行去…

如何使用大语言模型进行事件抽取与关系抽取

诸神缄默不语-个人CSDN博文目录 文章目录 1. 什么是事件抽取与关系抽取&#xff1f;2. 示例&#xff1a;使用大语言模型进行事件抽取与关系抽取 1. 什么是事件抽取与关系抽取&#xff1f; 事件抽取是指从文本中识别出与某些“事件”相关的信息。这些事件通常包括动作、参与者、…

GoldenDB组件及对应的用户和进程

1. GoldenDB组件及对应的用户和进程 GoldenDB数据库由管理节点、全局事务节点GTM、计算节点CN、数据节点DN等组成。 1.1. 管理节点 管理节点分为集群管理、Insight运维管理平台&#xff08;InsightServer、RDB、ZK&#xff09;。 1.1.1. 集群管理 1. 集群管理包括Metadatas…

认识编程-从思维方面看编程

如果说艺术通过色彩、线条和旋律将人类内心深处的梦想具象化&#xff0c;使之成为可以感知的视觉或听觉作品&#xff0c;那么计算机程序则是在数字世界中以逻辑和算法为画笔&#xff0c;描绘着创作者的构思与愿望。 编程是实现这一过程的语言和工具&#xff0c;它让那些抽象的…

小程序分包优化实践:解决主包过大和vendor.js体积问题

随着 uniapp 开发的小程序功能越来越复杂&#xff0c;主包的大小也逐渐增长&#xff0c;导致上传代码时遇到了2MB的限制。同时&#xff0c;由于微信小程序tabbar页面必须放在主包中&#xff0c;这进一步增加了主包的负担。为了提高用户体验并遵守平台规则&#xff0c;我们有必要…

Java Day1回顾简介-----变量命名规则

Java 简介、开发环境配置 菜鸟教程 编译运行 javac HelloWorld.java java HelloWorld Hello World public class HelloWorld {public static void main(String[] args) {System.out.println("Hello World");} }JAVA基础语法 类、对象、方法、实例、变量 对象&a…

vue3 + element-ui + vue router的使用教程 基于HBuilderX

文章目录 前言1.安装vue router2.创建一个router.js文件 封装router3.在main.js中导入router.js4.使用el-menu5.在el-menu使用vue router6.运行项目查看效果如下 前言 开发环境基于 HBuilderX 本文主要介绍 element-ui的el-menu组件结合vue router的使用教程 el-menu组件 &am…

Dockerfile运行指令

1.RUN 在build构建时执行命令。 举例&#xff1a;安装vim Shell命令格式 RUN yum install -y vim Exec命令格式 RUN ["yum","install","-y","vim"] 2.CMD 用于设置容器启动时默认执行的命令或参数。 如果Dockerfile中有多个CMD&a…

【经管】上市公司供应链风险数据测算数据集+dofile(2008-2023年)

A股上市公司企业供应链风险是指在企业运营过程中&#xff0c;由于供应链各环节的波动和不稳定&#xff0c;导致企业面临的生产、销售和财务风险。随着市场环境的变化&#xff0c;A股上市公司在全球化竞争中暴露出越来越多的供应链风险问题。 一、A股上市公司企业供应链风险的介…

记录一个我在idea启动时的报错

这几天我的idea突然就不能用了我就想着下一个新的&#xff0c;但是却一直报错报错内容如下 这个是我在网上截的pycharm的。 我在网上查了很多方法都不能用&#xff0c;今天重写安装发现我点了关联.java 和.pom和创建环境变量 这几个只需要创建一个快捷方式就行。我重新安装之…

HTML5新特性|01 音频视频

音频 1、Audio (音频) HTML5提供了播放音频文件的标准 2、control(控制器) control 属性供添加播放、暂停和音量控件 3、标签: <audio> 定义声音 <source> 规定多媒体资源,可以是多个<!DOCTYPE html> <html lang"en"> <head><…

138.WEB渗透测试-信息收集-小程序、app(9)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;137.WEB渗透测试-信息收集-小程序、app&#xff08;8&#xff09; 小程序的信息收集&…

TSN:工业通信的未来

一.传统以太网 1.竞争传输 传统以太网是基于竞争的传统以太网通信机制&#xff0c;当多个PC需要同一链路传输数据时&#xff0c;此时多个PC会竞争链路的使用权&#xff08;CSMA/CA&#xff09;。 如上图所示&#xff0c;当ES1向ES3传输大量非关键流量&#xff08;BE&#xff0…

如何将联系人从Android转移到 OPPO? [解决了]

概括 OPPO Reno4系列预计将于2020年10月1日上午9点30分举行线上发布会。从其官方预告片中我们不难发现&#xff0c;OPPO Reno4旗舰手机试图诠释梦想、挑战、勇气、自信和可能性。 3D曲面屏&#xff0c;图形流畅&#xff0c;机身更轻薄&#xff0c;色彩真实。听起来棒极了&…

[羊城杯 2024]不一样的数据库_2

题目描述&#xff1a; 压缩包6 (1).zip需要解压密码&#xff1a; 尝试用ARCHPR工具爆破一下&#xff1a; &#xff08;字典可自行在github上查找&#xff09; 解压密码为&#xff1a;753951 解压得到13.png和Kee.kdbx文件&#xff1a; 二维码图片看上去只缺了正常的三个角&…

MIT实验笔记冲刺3:页表操作(理论部分)

目录 分页硬件 内核地址空间 代码&#xff1a;创建地址空间 物理内存分配 代码&#xff1a;物理内存分配器 进程地址空间 代码&#xff1a;sbrk 代码&#xff1a;exec 实际的操作系统 这个实验将重点放到了我们的页表上&#xff0c;实际上&#xff0c;页表在我们上一个…

二、SQL语言,《数据库系统概念》,原书第7版

文章目录 一、概览SQL语言1.1 SQL 语言概述1.1.1 SQL语言的提出和发展1.1.2 SQL 语言的功能概述 1.2 利用SQL语言建立数据库1.2.1 示例1.2.2 SQL-DDL1.2.2.1 CREATE DATABASE1.2.2.2 CREATE TABLE 1.2.3 SQL-DML1.2.3.1 INSERT INTO 1.3 用SQL 语言进行简单查询1.3.1 单表查询 …