优化相关

  • 使用灵活的、动态分配的数据,不要使用固定大小多数组;
  • 优先使用线性算法或者尽可能快的算法:

    1. push_back 散列表查询:O(1)
    2. set/map lower_bound/upper_bound: O(logN)
    3. vector::insert for_each O(N)
  • 尽可能避免劣于线性复杂性的算法,永远不要使用指数复杂性的算法;

  • 不要进行不成熟的优化:
    1. 可以用通过引用传递的时候,却定义了通过值传递的方式传递参数;
    2. 可以使用前缀++、--运算的时候,却使用了后缀的方式;
    3. 构造函数中使用赋值操作而非初始化列表

并发编程

  • 尽量减少全局和共享数据
    避免使用名字空间作用域中具有外部连接的数据或者作为静态类成员的数据。如果不得不用,一定要对其仔细进行初始化。在不同编译单位中这种对象的初始化顺序是未定义的,为此需要高度注意;另外,名字空间作用域中的对象、静态数据成员对象或者跨线程(进程)共享的对象会减少并行性,往往是产生性能和可伸缩性瓶劲的原因。

例外情况: cin/cout/cerr 比较特殊: cout << "hello world" 等价于
(cout, "hello world");

  • 使用C++编写可靠的多线程的代码,认真考虑下面的建议:

    1. 参考目标平台的文档,了解改平台的同步原语,比如原子操作、内存屏障
    2. 最好将平台的原语用自己设计的抽象包装起来:比如使用pthread;
    3. 确保正在使用的类型在多线程程序中使用是安全的:
      保证非共享的对象独立;
      确定在不同线程中使用该类型的同一个对象到底是不是需要加锁、考虑最合适的加锁粒度;
  • 如果编写可能用于多线程的类型,必须完成两项任务:

    1. 确保不同线程可以不加锁地使用该类型的不同对象;
    2. 必须明确且提供不同线程使用该类型的同一个对象需要做的操作:
      是否需要考虑外部加锁: 调用者自己负责加锁
      是否需要内部加锁:为每个公有成员函数的操作加锁。比如生产者-消费者模型通常使用内部加锁。需要考虑:
      第一、 确认该类型的对象总是要被跨线程共享;
      第二、类型接口的设计应该有利于粗粒度、自给自足的操作。如果内部的锁加得很合适,那么对调用者而言是透明无感的。
      第三、不变对象(只读的、常量字符串)不需加锁。
  • 确保资源为对象所拥有,使用显式的RAII和智能指针
    1. 使用RAII时,小心复制构造函数和赋值构造函数;
    2. 使用智能指针而非原始指针来保存动态分配的资源:shared_ptr<T *>
    3. 应该显式地执行资源分配(比如new);
    4. 马上将申请分配的资源赋予给管理对象:

比如:
void Fun(shared_ptr<Widget> sp1, shared_ptr<Widget> sp2);
Fun(shared_ptr<Widget>(new Widget), shared_ptr<Widget>(new Widget));

由于参数初始化的顺序可能因为编译器的不同而改变,一种极端的情况是:
同时执行了对两个对象的new 操作的内存分配操作,然后再试图调用两个Widget 构造函数。如果这个时候某个构造函数调用抛出异常,另外一个对象的内存就永远没有机会释放了。

解决方法:绝对不要在一条语句中分配一个以上的资源,应该显式地执行资源分配(比如new),然后马上将申请分配的资源赋予给管理对象。例如:

shared_ptr<Widget> sp1(new Widget);
shared_ptr<Widget> sp2(new Widget);

Fun(sp1, sp2);

C++ 进阶笔记之一的更多相关文章

  1. Angularjs进阶笔记(2)-自定义指令中的数据绑定

    有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...

  2. javascript进阶笔记(2)

    js是一门函数式语言,因为js的强大威力依赖于是否将其作为函数式语言进行使用.在js中,我们通常要大量使用函数式编程风格.函数式编程专注于:少而精.通常无副作用.将函数作为程序代码的基础构件块. 在函 ...

  3. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

  4. Android进阶笔记:AIDL内部实现详解 (二)

    接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...

  5. javascript进阶笔记(1)

    学习js已经有一段时间了,大大小小还是能够做出一些东西来.不过觉得可惜的是,还是对js本身这门语言不是很熟悉,总有一点雾里看花的感觉,看得见,但是看不清楚.最近发现有一本关于js的叫做<忍者秘籍 ...

  6. object - c 语言基础 进阶笔记 随笔笔记

    重点知识Engadget(瘾科技)StackOverFlow(栈溢出)Code4Apprespon魏先宇的程序人生第一周快捷键: Alt+上方向键 跳到最上面  Alt+下方向键 跳到最下面      ...

  7. python进阶笔记 thread 和 threading模块学习

    Python通过两个标准库thread和threading提供对线程的支持.thread提供了低级别的.原始的线程以及一个简单的锁.threading基于Java的线程模型设计.锁(Lock)和条件变 ...

  8. Android进阶笔记20:Android手机屏幕坐标系

    1. 手机屏幕坐标系: 整个坐标系是以手机屏幕左上角为原点(0,0),如下:

  9. Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch

    1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...

  10. Android进阶笔记18:选用合适的IPC方式

    1. 相信大家都知道Android进程间通信方式很多,比如AIDL.Messenger等等,接下来我就总结一下这些IPC方式优缺点. 2. IPC方式的优缺点和适用场景 3. 附加:使用Intent实 ...

随机推荐

  1. openstack学习之neutron ml2初始化代码分析

    这里没有 去详细考虑neutron server怎么初始化的,而是直接从加载插件的地方开始分析.首先我们看下下面这个文件. Neutron/api/v2/router.py class APIRout ...

  2. 2017 CCPC秦皇岛 M题 Safest Buildings

    PUBG is a multiplayer online battle royale video game. In the game, up to one hundred players parach ...

  3. 使用stm32开发 USB_CAN 适配器测试

    USB_CAN 适配器测试例程 采用CDC透传模式 一.简介 CAN总线无处不在,在设计开发中,到处需要用到CAN总线调试工具,本工具可以作为CAN的基础测试工具,用于监听CAN总线,或测试CAN数据 ...

  4. Python3 数据结构之词频统计(英文)

    import string path = r'C:\Users\Black\Desktop\Walden.txt' with open(path, 'r', encoding='utf-8') as ...

  5. Day 06 流程控制和爬虫基础2

    目录 if 判断 单分支结构 双分支结构 多分支结构 for循环 for循环的基本用法 for循环嵌套 break continue 爬虫基础2 爬取豆瓣TOP250 爬取豆瓣数据接口(异步数据) 爬 ...

  6. org json 和 fast json 掺杂使用引起的错误

    1. 取值的不同 当所取得key不存在时: org json 会抛异常 fast json 会返回null 示例: com.alibaba.fastjson.JSONObject fastJson = ...

  7. 【Visual Studio Code】插件

    [Visual Studio Code]插件 转载:https://www.cnblogs.com/yangchongxing/p/10625628.html 目录 ================= ...

  8. js打乱数组排序

    用到的知识点:Math.random()//用于打乱数组索引 random() 方法可返回介于 0(包含) ~ 1(不包含) 之间的一个随机数. var arr=[1,2,3,4,5,6]; for( ...

  9. Django序列化时间报错

    一.前言 当利用models模块从数据库获取数据时,当获的取数据序列化时,如果获取的数据中有关于时间类型的字段,则会报错,错误如下: TypeError: datetime.datetime(2018 ...

  10. 记一次 Kafka 集群线上扩容

    前段时间收到某个 Kafka 集群的生产客户端反馈发送消息耗时很高,于是花了一段时间去排查这个问题,最后该集群进行扩容,由于某些主题的当前数据量实在太大,在对这些主题迁移过程中话费了很长一段时间,不过 ...