面向亿行 C/C++ 代码的静态分析系统设计及实践-肖枭代码质量管理是个大问题 静态分析+代码评审的实践 学习和强调,红线和惩罚,100%的测试 覆盖率,和事后复盘并不够 有经验的程序员也会犯错 对代码提要求很难监督落实 测试更多是验证功能,很难检测编码缺陷 代码的快速变化使质量更难管 生产质量是责任 靠运维和事后复盘善后够吗? 静态分析工具:半智能的代码分析机器人 静态分析辅助代码评审 自动化工具+流程才是未来 降低感知误报率 用数据风控的方式管理 总结:代码评审中的静态分析 无需额外操作,不改变程序员习惯的流程 只分析变化的代码引起的问题 使用频次高,可形成数据驱动的分析器改进和 代码质量监控 推动规范落地和培训教育新员工 提高人工评审效果 零培训成本强制使用 基于gitlab的自动代码评审演示0 码力 | 39 页 | 6.88 MB | 1 年前3
《深入浅出MFC》2/e遍。我在此再说一次。 1998 年中,本书之发行公司松岗(UNALIS)即希望我授权简体版,然因当时 我已在构思3/e,预判3/e 繁体版出版时,2/e 简体版恐怕还未能完成。老是让 大陆读者慢一步看到我的书,令我至感难过,所以便请松岗公司不要进行2/e 简 体版之授权,直接等3/e 出版后再动作。没想到一拖经年,我的3/e 写作计划 并没有如期完成,致使大陆读者反而没有《深入浅出MFC》2/e 把进货原料改一改、发酵程序改一 改、瓶装程序改一改、整个厂的其它设备以及设备与设备之间的联机配合(这是顶顶重 要的)都可以再利用。物料之后到生管,装瓶之后到仓贮,仓贮之后到出货,再加上MIS 监控全厂,这些程序都是不必改变的。 一个整厂整线计划,每一单元之间的联机沟通,合作关系,都已经建立起来,是一种建 构好的运作模式。抽换某个单元的性质或部份性质,并不影响整体操作。「整厂整线」 最重要最有价值的是各单元之间的流程与控制。 中采用的两个类别。深色部份是 Scribble 范例程序在32 位MFC 中采用的两个类别。 第8章 Document-View 深入探討 469 List Yes No 快 慢 可 Array Yes Yes 慢 慢 可 Map No Yes 快 快 MFC Collection Classes 的选用 第5章末尾我曾经大致提过MFC Collection Classes。它们分为三种类型,用来管理一大0 码力 | 1009 页 | 11.08 MB | 1 年前3
Hello 算法 1.0.0b2 C++版效率评估方法 实际测试 假设我们现在有算法 A 和 算法 B ,都能够解决同一问题,现在需要对比两个算法之间的效率。我们能够想到 的最直接的方式,就是找一台计算机,把两个算法都完整跑一遍,并监控记录运行时间和内存占用情况。这种 评估方式能够反映真实情况,但是也存在很大的硬伤。 难以排除测试环境的干扰因素。硬件配置会影响到算法的性能表现。例如,在某台计算机中,算法 A 比算法 B 运行时 的时间增长趋势 相比直接统计算法运行时间,时间复杂度分析的做法有什么好处呢?以及有什么不足? 时间复杂度可以有效评估算法效率。算法 B 运行时间的增长是线性的,在 ? > 1 时慢于算法 A ,在 ? > 1000000 时慢于算法 C 。实质上,只要输入数据大小 ? 足够大,复杂度为「常数阶」的算法一定优于 「线性阶」的算法,这也正是时间增长趋势的含义。 时间复杂度的推算方法更加简便。在时间复 时间,再在数组中删除该元素,使用 ?(?) 时间; ‧ 获取最小 / 最大元素:数组头部和尾部元素即是最小和最大元素,使用 ?(1) 时间; 观察发现,无序数组和有序数组中的各项操作的时间复杂度是“偏科”的,即有的快有的慢;而二叉搜索树的 各项操作的时间复杂度都是对数阶,在数据量 ? 很大时有巨大优势。 无序数组 有序数组 二叉搜索树 查找指定元素 ?(?) ?(log ?) ?(log ?) 插入元素 ?(1)0 码力 | 197 页 | 15.72 MB | 1 年前3
Hello 算法 1.0.0b1 C++版效率评估方法 实际测试 假设我们现在有算法 A 和 算法 B ,都能够解决同一问题,现在需要对比两个算法之间的效率。我们能够想到 的最直接的方式,就是找一台计算机,把两个算法都完整跑一遍,并监控记录运行时间和内存占用情况。这种 评估方式能够反映真实情况,但是也存在很大的硬伤。 难以排除测试环境的干扰因素。硬件配置会影响到算法的性能表现。例如,在某台计算机中,算法 A 比算法 B 运行时 的时间增长趋势 相比直接统计算法运行时间,时间复杂度分析的做法有什么好处呢?以及有什么不足? 时间复杂度可以有效评估算法效率。算法 B 运行时间的增长是线性的,在 ? > 1 时慢于算法 A ,在 ? > 1000000 时慢于算法 C 。实质上,只要输入数据大小 ? 足够大,复杂度为「常数阶」的算法一定优于 「线性阶」的算法,这也正是时间增长趋势的含义。 时间复杂度的推算方法更加简便。在时间复 时间,再在数组中删除该元素,使用 ?(?) 时间; ‧ 获取最小 / 最大元素:数组头部和尾部元素即是最小和最大元素,使用 ?(1) 时间; 观察发现,无序数组和有序数组中的各项操作的时间复杂度是“偏科”的,即有的快有的慢;而二叉搜索树的 各项操作的时间复杂度都是对数阶,在数据量 ? 很大时有巨大优势。 无序数组 有序数组 二叉搜索树 查找指定元素 ?(?) ?(log ?) ?(log ?) 插入元素 ?(1)0 码力 | 187 页 | 14.71 MB | 1 年前3
Hello 算法 1.0.0b4 C++版化过程。 2.1.2. 效率评估方法 实际测试 假设我们现在有算法 A 和算法 B,它们都能解决同一问题,现在需要对比这两个算法的效率。我们最直接的 方法就是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够 反映真实情况,但也存在较大局限性。 难以排除测试环境的干扰因素。硬件配置会影响算法的性能表现。例如,在某台计算机中,算法 A 的运行时 间比算法 的时间增长趋势 相较于直接统计算法运行时间,时间复杂度分析有哪些优势和局限性呢? 时间复杂度能够有效评估算法效率。例如,算法 B 的运行时间呈线性增长,在 ? > 1 时比算法 A 慢,在 ? > 1000000 时比算法 C 慢。事实上,只要输入数据大小 ? 足够大,复杂度为「常数阶」的算法一定优于 「线性阶」的算法,这正是时间增长趋势所表达的含义。 时间复杂度的推算方法更简便。显然,运行平台和计 计数排序适用于数据量大但数据范围较小的情况。比如,在上述示例中 ? 不能太大,否则会占用过多空间。 而当 ? ≪ ? 时,计数排序使用 ?(?) 时间,可能比 ?(? log ?) 的排序算法还要慢。 11.10. 基数排序 上一节我们介绍了计数排序,它适用于数据量 ? 较大但数据范围 ? 较小的情况。假设我们需要对 ? = 106 个学号进行排序,而学号是一个 8 位数字,这意味着数据范围0 码力 | 343 页 | 27.39 MB | 1 年前3
Hello 算法 1.1.0 C++ 版效率评估方法主要分为两种:实际测试、理论估算。 2.1.1 实际测试 假设我们现在有算法 A 和算法 B ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法 是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真 实情况,但也存在较大的局限性。 一方面,难以排除测试环境的干扰因素。硬件配置会影响算法的性能。比如在某台计算机中,算法 A 的运行 时间比算法 自的特 点,从而导致以下不同点。 1. 分配和释放效率:栈是一块较小的内存,分配由编译器自动完成;而堆内存相对更大,可以在代码中动 态分配,更容易碎片化。因此,堆上的分配和释放操作通常比栈上的慢。 2. 大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。 3. 灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。 Q:为什么 计数排序适用于数据量大但数据范围较小的情况。比如,在上述示例中 ? 不能太大,否则会占用过多空间。 而当 ? ≪ ? 时,计数排序使用 ?(?) 时间,可能比 ?(? log ?) 的排序算法还要慢。 11.10 基数排序 上一节介绍了计数排序,它适用于数据量 ? 较大但数据范围 ? 较小的情况。假设我们需要对 ? = 106 个学 号进行排序,而学号是一个 8 位数字,这意味着数据范围0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.0.0 C++版效率评估方法主要分为两种:实际测试、理论估算。 2.1.1 实际测试 假设我们现在有算法 A 和算法 B ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法 是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真 实情况,但也存在较大的局限性。 一方面,难以排除测试环境的干扰因素。硬件配置会影响算法的性能。比如在某台计算机中,算法 A 的运行 时间比算法 自的特 点,从而导致以下不同点。 1. 分配和释放效率:栈是一块较小的内存,分配由编译器自动完成;而堆内存相对更大,可以在代码中动 态分配,更容易碎片化。因此,堆上的分配和释放操作通常比栈上的慢。 2. 大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。 3. 灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。 Q:为什么 计数排序适用于数据量大但数据范围较小的情况。比如,在上述示例中 ? 不能太大,否则会占用过多空间。 而当 ? ≪ ? 时,计数排序使用 ?(?) 时间,可能比 ?(? log ?) 的排序算法还要慢。 第 11 章 排序 hello‑algo.com 254 11.10 基数排序 上一节介绍了计数排序,它适用于数据量 ? 较大但数据范围 ? 较小的情况。假设我们需要对 ? = 106 个学0 码力 | 378 页 | 17.59 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 为什么往 int 数组里赋值 1 比赋值 0 慢一倍? 第 1 章:内存带宽 cpu-bound 与 memory-bound • 通常来说,并行只能加速计算的部分,不能加速内存读写的部分 。 • 因此,对 fill 这种没有任何计算量,纯粹只有访存的循环体,并 64 字节分块地随机访问 • 解决方法就是,把数据按 64 字节大小分块。随 机访问时,只随机块的位置,而块的内部仍然按 顺序访问。 • 可以看到 64 字节分块的效果拔群,但还是比顺 序访问慢一些,为什么?明明没有浪费带宽了? 缓存行预取技术:吃着一碗饭的同时,先喊妈妈烧下一碗饭 • 其实,当程序顺序访问 a[0], a[1] 时, CPU 会智能地预测到你接下来可 能会读取 a[2] 次的程序还是会无法达到 mem-bound ,手动预取以后才能达到,就是因为硬件预取预测失败,导致不得不等 内存抵达了才能算,导致延迟隐藏失败。隐藏失败: a[0] a[1] a[2] 为什么写入比读取慢? • 注意到一个现象:写入花的时间似乎是读取的 2 倍? • 而且写入的同时读取,和单单写入的时间是一样的? • 似乎写入一个数组的同时也会读取这个数组,造成两倍带宽 ? 写入的粒度太小造成不必要的读取0 码力 | 147 页 | 18.88 MB | 1 年前3
Hello 算法 1.2.0 简体中文 C++ 版效率评估方法主要分为两种:实际测试、理论估算。 2.1.1 实际测试 假设我们现在有算法 A 和算法 B ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法 是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真 实情况,但也存在较大的局限性。 一方面,难以排除测试环境的干扰因素。硬件配置会影响算法的性能表现。比如一个算法的并行度较高,那 么它就更适合在多核 自的特 点,从而导致以下不同点。 1. 分配和释放效率:栈是一块较小的内存,分配由编译器自动完成;而堆内存相对更大,可以在代码中动 态分配,更容易碎片化。因此,堆上的分配和释放操作通常比栈上的慢。 2. 大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。 3. 灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。 Q:为什么 计数排序适用于数据量大但数据范围较小的情况。比如,在上述示例中 ? 不能太大,否则会占用过多空间。 而当 ? ≪ ? 时,计数排序使用 ?(?) 时间,可能比 ?(? log ?) 的排序算法还要慢。 11.10 基数排序 上一节介绍了计数排序,它适用于数据量 ? 较大但数据范围 ? 较小的情况。假设我们需要对 ? = 106 个学 号进行排序,而学号是一个 8 位数字,这意味着数据范围0 码力 | 379 页 | 18.48 MB | 10 月前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vectorreserve 解决 • 因此,如果你早就知道要推入元素的数量,可以调用 reserve 函数先预留那么多的容量,等待接下来的推入 。 • 这样之后 push_back 时,就不会一次次地扩容两倍慢 慢成长到 128 ,避免重新分配内存和移动元素,更高效 。 • 比如这里我们可以提前知道循环会执行 100 次,因此 reserve(100) 就可以了。 • 可以看到只有一次 malloc(400)0 码力 | 90 页 | 4.93 MB | 1 年前3
共 19 条
- 1
- 2













