快捷搜索:

您的位置:澳门新葡4473网站 > 新葡亰平台娱乐 > 看一名 KDE 开发者如何使用 C++17 为项目提升巨大

看一名 KDE 开发者如何使用 C++17 为项目提升巨大

发布时间:2020-01-09 17:57编辑:新葡亰平台娱乐浏览(167)

    特别是,Antonio 专注于加速在用户的本地音乐收藏中寻找歌曲/音乐副本的过程。最初的代码通过 Python 实现,后来变成了经过优化的 C++ 代码。令人惊讶的是,优化调整过的 C++ 代码要比 Python 快得多 —— 如果你希望了解作者为实现这个结果所做出的调整,以及所采取的各种步骤带来的影响,不妨看看作者所写的博客。

    第二部分

    他没有用 C++ 重写整个程序,而是使用了 Boost.Python 库,该库使得 C++ 和 Python 代码之间可进行无缝的操作。从这时开始,Antonio 开始编写相关的 C++ 代码。特别是,他专注于 C++ 17 并使用了线程。进一步提升性能的操作是调整 C++ 的编译器标记(compiler flags),并将 GCC 从 7.3 版本切换到 8.1 版本。

        有益的提醒,静态编译的代码仍然重要. 仅例举几例, Chrome,Firefox,MySQL,MS Office 和 Photoshop都是高度优化的软件,我们每天都在使用. Python作为解析语言,很明显不适合. 不能单靠Python来满足那些性能是首要指示的领域. 这就是为什么Python支持让你接触底层裸机基础设施的原因, 将更繁重的工作代理给更快的语言如C. 这高性能计算和嵌入式编程中是关键的功能. Python性能鸡汤第一部分讨论了怎样高效的使用Python. 在第二部分, 我们將涉及监控和扩展Python.

    长话短说,“作者的最后一次代码提交也最后一次提升了速度,达到 7998 倍 —— 36680首/秒(对比速度),并可在13秒内完全处理完一个1000首歌曲的音乐集。”有关更详细具体的技术细节请查看作者原博客,也可以访问他的 Bard 音乐管理器项目以了解更多。

    1. 首先, 拒绝调优诱惑
         调优给你的代码增加复杂性. 集成其它语言之前, 请检查下面的列表. 如果你的算法是“足够好”, 优化就没那么迫切了.
      1) 你做了性能测试报告吗?
      2) 你能减少硬盘的 I/O 访问吗?
      3) 你能减少网络 I/O 访问吗?
      4) 你能升级硬件吗?
      5) 你是为其它开发者编译库吗?
      6)你的第三方库软件是最新版吗?

    2. 使用工具监控代码, 而不是直觉
          速度的问题可能很微妙, 所以不要依赖于直觉. 感谢 “cprofiles” 模块, 通过简单的运行你就可以监控Python代码 ,如下:
      “python -m cProfile myprogram.py”
      我们写了个测试程序. 基于黑盒监控. 这里的瓶颈是 “very_slow()” 函数调用. 我们还可以看到 “fast()” 和 “slow()”都被调用200次. 这意味着, 如果我们可以改善 “fast()” 和 “slow()” 函数, 我们可以获得全面的性能提升. cprofiles 模块也可以在运行时导入. 这对于检查长时间运行的进程非常有用.

    3. 审查时间复杂度
          控制以后, 提供一个基本的算法性能分析. 恒定时间是理想值. 对数时间复度是稳定的. 阶乘复杂度很难扩展.

    O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!)

     

    1. 使用第三方包

       有很多为Python设计的高性能的第三方库和工具. 下面是一些有用的加速包的简短列表.

    1) NumPy: 一个开源的相当于MatLab的包

    2) SciPy: 另一个数值处理库

    3) GPULib: 使用GPUs加速代码

    4) PyPy: 使用 just-in-time 编译器优化Python代码

    5) Cython: 將Python优码转成C

    6)ShedSkin: 將Python代码转成C++

    1. 使用multiprocessing模块实现真正的并发

           因为GIL会序列化线程, Python中的多线程不能在多核机器和集群中加速. 因此Python提供了multiprocessing模块, 可以派生额外的进程代替线程, 跳出GIL的限制. 此外, 你也可以在外部C代码中结合该建议, 使得程序更快.注意, 进程的开销通常比线程昂贵, 因为线程自动共享内存地址空间和文件描述符. 意味着, 创建进程比创建线程会花费更多, 也可能花费更多内存. 这点在你计算使用多处理器时要牢记.

    1. 本地代码

          好了, 现在你决定为了性能使用本地代码. 在标准的ctypes模块中, 你可以直接加载已编程的二进制库(.dll 或 .so文件)到Python中, 无需担心编写C/C++代码或构建依赖. 例如, 我们可以写个程序加载libc来生成随机数.然而, 绑定ctypes的开销是非轻量级的. 你可以认为ctypes是一个粘合操作系库函数或者硬件设备驱动的胶水. 有几个如 SWIG, Cython和Boost 此类Python直接植入的库的调用比ctypes开销要低. Python支持面向对象特性, 如类和继承. 正如我们看到的例子, 我们可以保留常规的C++代码, 稍后导入. 这里的主要工作是编写一个包装器 (行 10~18).

    最后作者也就这次优化总结了一些心得:

    总结:

    • 花一些时间思考如何优化代码 —— 这件事十分值得开发者去做

    • 如果你使用 C++ 并能够使用现代编译器,那么请使用 C++ 17,它可以让你更有效地编写更好/更优雅的代码。Lambdas、结构化绑定、constexpr 等特性真的值得花时间阅读它们

    • 允许编译器为你做的事情。,它可以对你的代码进行优化而无需你的任何努力

    • 尽可能少地复制/移动数据。这个操作很慢,很多时候只需要在开发之前考虑一下数据结构就可以避免这个操作

    • 尽可能使用线程

    • 最后,可能也是最重要的:量化一切指标。你不能改进你无法量化的东西(嗯,技术上你可以,但你肯定不知道)

    我希望这些Python建议能让你成为一个更好的开发者. 最后, 我需要指出, 追求性能极限是一个有趣的游戏, 而过度优化就会变成嘲弄了. 虽然Python授予你与C接口无缝集成的能力, 你必须问自己你花数小时的艰辛优化工作用户是否买帐. 另一方面, 牺牲代码的可维护性换取几毫秒的提升是否值得. 团队中的成员常常会感谢你编写了简洁的代码. 尽量贴近Python的方式, 因为人生苦短. :)

    参考 https://www.phoronix.com/

    本文由澳门新葡4473网站发布于新葡亰平台娱乐,转载请注明出处:看一名 KDE 开发者如何使用 C++17 为项目提升巨大

    关键词: