有时候除了测量算法的具体性能指数,我们也会希望测试出算法的时间复杂度,以便我们对待测试的算法的性能有一个更加直观的了解。

测量时间复杂度

google benchmark已经为我们提供了类似的功能,而且使用相当简单。

具体的解释在后面,我们先来看几个例子,我们人为制造几个时间复杂度分别为O(n), O(logn), O(n^n)的测试用例:

  1. // 这里都是为了演示而写成的代码,没有什么实际意义
  2. static void bench_N(benchmark::State& state)
  3. {
  4. int n = 0;
  5. for ([[maybe_unused]] auto _ : state) {
  6. for (int i = 0; i < state.range(0); ++i) {
  7. benchmark::DoNotOptimize(n += 2); // 这个函数防止编译器将表达式优化,会略微降低一些性能
  8. }
  9. }
  10. state.SetComplexityN(state.range(0));
  11. }
  12. BENCHMARK(bench_N)->RangeMultiplier(10)->Range(10, 1000000)->Complexity();
  13. static void bench_LogN(benchmark::State& state)
  14. {
  15. int n = 0;
  16. for ([[maybe_unused]] auto _ : state) {
  17. for (int i = 1; i < state.range(0); i *= 2) {
  18. benchmark::DoNotOptimize(n += 2);
  19. }
  20. }
  21. state.SetComplexityN(state.range(0));
  22. }
  23. BENCHMARK(bench_LogN)->RangeMultiplier(10)->Range(10, 1000000)->Complexity();
  24. static void bench_Square(benchmark::State& state)
  25. {
  26. int n = 0;
  27. auto len = state.range(0);
  28. for ([[maybe_unused]] auto _ : state) {
  29. for (int64_t i = 1; i < len*len; ++i) {
  30. benchmark::DoNotOptimize(n += 2);
  31. }
  32. }
  33. state.SetComplexityN(len);
  34. }
  35. BENCHMARK(bench_Square)->RangeMultiplier(10)->Range(10, 100000)->Complexity();

如何传递参数和生成批量测试我们在上一篇已经介绍过了,这里不再重复。

需要关注的是新出现的state.SetComplexityNComplexity

首先是state.SetComplexityN,参数是一个64位整数,用来表示算法总体需要处理的数据总量。benchmark会根据这个数值,再加上运行耗时以及state的迭代次数计算出一个用于后面预估平均时间复杂度的值。

Complexity会根据同一组的多个测试用例计算出一个较接近的平均时间复杂度和一个均方根值,需要和state.SetComplexityN配合使用。

Complexity还有一个参数,可以接受一个函数或是benchmark::BigO枚举,它的作用是提示benchmark该测试用例的时间复杂度,默认值为benchmark::oAuto,测试中会自动帮我们计算出时间复杂度。对于较为复杂的算法,而我们又有预期的时间按复杂度,这时我们就可以将其传给这个方法,比如对于第二个测试用例,我们还可以这样写:

  1. static void bench_LogN(benchmark::State& state)
  2. {
  3. // 中间部分与前面一样,略过
  4. }
  5. BENCHMARK(bench_LogN)->RangeMultiplier(10)->Range(10, 1000000)->Complexity(benchmark::oLogN);

在选择正确的提示后对测试结果几乎没有影响,除了偏差值可以降得更低,使结果更准确。

Complexity在计算时间复杂度时会保留复杂度的系数,因此,如果我们发现给出的提示的时间复杂度前的系数过大的话,就意味着我们的预估发生了较大的偏差,同时它还会计算出RMS值,同样反应了时间复杂度的偏差情况。

运行我们的测试:

可以看到,自动的时间复杂度计算基本是准确的,可以在我们对算法进行测试时提供一个有效的参考。

c++性能测试工具:计算时间复杂度的更多相关文章

  1. c++性能测试工具:google benchmark进阶(一)

    这是c++性能测试工具教程的第四篇文章,从本篇开始我将逐步介绍一些性能测试的高级技巧. 前三篇教程可以看这里: c++性能测试工具:google benchmark入门(一) c++性能测试工具:go ...

  2. 给CentOS6.3 + PHP5.3 安装PHP性能测试工具 XHProf-0.9.2

    一.什么是XHProf XHProf官网:http://pecl.php.net/package/xhprof XHProf是一个分层PHP性能分析工具.它报告函数级别的请求次数和各种指标,包括 阻塞 ...

  3. Android性能测试工具APT使用指南

    腾讯的安卓平台高效的性能测试工具APT(Android Performance Testing Tools),适用于开发自测和定位性能瓶颈,帮助测试人员完成性能基准测试.竞品测试. APT提供了CPU ...

  4. 性能测试工具 转自https://yq.aliyun.com/articles/35149?spm=5176.100239.blogcont35147.8.rsow6k

    摘要: 继续这个系列的学习,这一节重点介绍目前流行的性能测试工具以及如何选择适合项目的工具.在此之前,我已经对性能测试工具的原理与架构做了分析. http://www.cnblogs.com/fnng ...

  5. 网络性能测试工具iperf详细使用图文教程

      Iperf是一个网络性能测试工具.Iperf可以测试TCP和UDP带宽质量.Iperf可以测量最大TCP带宽,具有多种参数和UDP特性. Iperf可以报告带宽,延迟抖动和数据包丢失.利用Iper ...

  6. 网络性能测试工具iperf详细使用图文教程【转载】

    原文:http://blog.163.com/hlz_2599/blog/static/142378474201341341339314/ 参考:http://man.linuxde.net/iper ...

  7. python模块介绍- multi-mechanize 性能测试工具

    python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...

  8. 【腾讯开源】Android性能测试工具APT使用指南

    [腾讯开源]Android性能测试工具APT使用指南 2014-04-23 09:58 CSDN CODE 作者 CSDN CODE 17 7833 腾讯 apt 安卓 性能测试 开源 我们近日对腾讯 ...

  9. 负载,性能测试工具-Gatling

    前言 Gatling Gatling是一款功能强大的负载测试工具,它为易于使用,高可维护性和高性能而设计. 开箱即用,Gatling由于对HTTP协议的出色支持,使其成为负载测试任何HTTP服务器的首 ...

随机推荐

  1. ssh框架被淘汰的原因

    SSH就是Struts2+Spring+Hibernate. 三个组件的简单介绍 Struts2:通俗的讲就是为了完成MVC模型中的C的功能,也就是编写具体的业务逻辑的地方.从他的设计上来看就是请求到 ...

  2. Window权限维持(一):注册表运行键

    在红队行动中在网络中获得最初的立足点是一项耗时的任务.因此,持久性是红队成功运作的关键,这将使团队能够专注于目标,而不会失去与指挥和控制服务器的通信.在Windows登录期间创建将执行任意负载的注册表 ...

  3. Ubuntu1404配置jdk-12.0.2并安装Android Studio教程

    最近在学习Android Studio 移动应用程序开发,但Android Studio好像对win10不太友好,所以小帅想在Ubuntu上安装Android Studio.为此小帅还去网上找了相关教 ...

  4. ASP.NET list<object> OBJECT.clean()会清空session['OBJECT']的值的问题

    public partial class 测试 : System.Web.UI.Page { static List<Item> allAnswer= new List<Item&g ...

  5. 10道Python常见面试题

    1.MySQL索引种类 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引 2.索引在什么情况下遵循最左前缀的规则? 最左前缀原理的一部分,索引index1:(a,b,c),只会走a ...

  6. VMware与 Device/Credential Guard 不兼容,解决办法及心得

    以下为心路历程,想要直接解决可以直接拉到最后看后续 百度要你取消Hyper-V功能,但我要用docker,以及一些相关的帖子都无效的情况下 https://blog.csdn.net/u0136677 ...

  7. Windows 下MongoDB复制集配置

    1.下载服务.https://www.mongodb.com/   点击products 下拉第二列MongoDB server  选择 4.0.6 2.下载下来后 有限管理员运行 一路安装,可以不用 ...

  8. EF性能优化篇一

    https://www.cnblogs.com/chenwolong/p/7531955.html 1.合理使用AsNoTracking 若对查询的数据不需要做任何修改,则可采用AsNoTrackin ...

  9. GCN实现3

    参考 : 首先看两篇论文,大概了解一下原理性的东西: GRAPH CONVOLUTIONAL NETWORKS THOMAS KIPF, 30 SEPTEMBER 2016 http://tkipf. ...

  10. Python环境安装与基础语法(3)——进制、运算符和优先级、原码、补码

    进制 转十进制:基本运算方法(权算方式) 0b1111——>1*2**3 + 1*2**2 + 1*2**1 + 1*2**0 0x7F——>7*16**1 + F*16**0 转二进制: ...