【算法与数据结构】6 学会对算法进行性能测试

news/2024/4/19 8:34:46/文章来源:https://blog.csdn.net/qq_40332045/article/details/130356465

请添加图片描述

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流

本文收录于算法与数据结构体系专栏,本专栏对于0基础者极为友好,欢迎与我一起完成算法与数据结构的从0到1的跨越

请添加图片描述

算法性能测试

  • 一、前情回顾
  • 二、算法性能测试
    • 1.生成测试用例
    • 2.使用测试用例
      • 2.1 检验测试用例的用时
      • 2.1 不同规模的测试用例的用时比较

一、前情回顾

  • 👉传送门:1 详解线性查找法
  • 👉传送门:2 线性查找的优化
  • 👉传送门:3 线性查找的测试
  • 👉传送门:4 循环不变量与复杂度分析
  • 👉传送门:5 常见的时间复杂度

二、算法性能测试

Integer[] data = {24, 18, 12, 9, 16, 66, 32, 4};

我们对于之前的线性查找的算法,只是使用了一个含有8个元素的data数组进行测试,这个数组规模太小,在现代计算机上,对于 O ( n ) O(n) O(n)这个级别的复杂度,需要一定规模的数据才能看到相应的性能

1.生成测试用例

//作用:为我们生成一个数组,
public class ArrayGenerator {// 用户无需生成一个ArrayGenerator的对象,因此将构造函数设置为私有private ArrayGenerator(){}//使用静态方法//生成一个数组,数组中的元素是顺序存放public static Integer[] generateOrderedArray(int n){//对线性查找进行测试,所以生成的数组中的元素就是[0...n-1]//其中n的大小是变化的,是用户进行输入指定Integer[] arr = new Integer[n];for (int i = 0; i < n; i++) {arr[i] = i;}return arr;}
}
  • 新建一个ArrayGenerator类,专门用于生成数组
  • 数组生成中的方法采用静态方法,且用户无需生成一个ArrayGenerator的对象,因此将构造函数设置为私有
  • 此处主要用于测试前面的线性查找算法的性能,所以生成的数组中的元素顺序存放,范围 [ 0... n − 1 ] [0...n-1] [0...n1],其中n是由用户进行指定的

2.使用测试用例

public class LinearSearchGenerator {private LinearSearchGenerator(){}public static <E> int search(E[] data, E target) {for (int i = 0; i < data.length; i++) {if (data[i] == target)return i;    //如果找到目标,返回对应的索引值}return -1;          //如果没有找到目标,返回-1}public static void main(String[] args) {//准备用于查找的数组,数组中有100000个元素Integer[] data = ArrayGenerator.generateOrderedArray(100000);int res = LinearSearchGenerator.search(data, 100000);System.out.println(res); //输出res}
}
  • data数组直接使用ArrayGenerator.generateOrderedArray()生成
  • 首次传入的参数为100000,并且将查找的target值设为100000
    在这里插入图片描述
  • 很明显,在一个元素个数只有100000的数组中,且数组的元素是顺序存放的[0…100000),查询是否有100000这个数的结果一定是-1

2.1 检验测试用例的用时

  • 为了检验出对于这次查询,这次的函数调用具体消耗了多少时间,我们可以使用Java为我们提供的nanoTime()方法做一个计时
public class LinearSearchGenerator {private LinearSearchGenerator(){}public static <E> int search(E[] data, E target) {for (int i = 0; i < data.length; i++) {if (data[i] == target)return i;    //如果找到目标,返回对应的索引值}return -1;          //如果没有找到目标,返回-1}public static void main(String[] args) {int n = 100000;//准备用于查找的数组,数组中有100000个元素Integer[] data = ArrayGenerator.generateOrderedArray(n);//nanoTime()方法返回的其实是一个时间戳,// 是一个长整型,当前用纳秒计算的时间戳long startTime = System.nanoTime();int res = LinearSearchGenerator.search(data, n);System.out.println(res); //输出reslong endTime = System.nanoTime();//endTime - startTime的值就是两个时间戳之间的线性查找所用的时间,单位是纳秒//纳秒与秒之间是10^9//对于结果可以是一个浮点数,所以除以1000000000.0double time = (endTime - startTime) / 1000000000.0;System.out.println(time + " s");}
}
  • nanoTime()方法返回的其实是一个时间戳,用纳秒计算
  • 在线性查找算法前使用一次,在线性查找算法结束后使用一次
  • endTime - startTime的值就是两个时间戳之间的线性查找所用的时间,单位是纳秒
  • 结果如下:
    • 消耗时间也与硬件有关,所以时间不一定相同
      在这里插入图片描述

2.1 不同规模的测试用例的用时比较

public class LinearSearchGenerator {private LinearSearchGenerator() {}public static <E> int search(E[] data, E target) {for (int i = 0; i < data.length; i++) {if (data[i] == target)return i;    //如果找到目标,返回对应的索引值}return -1;          //如果没有找到目标,返回-1}public static void main(String[] args) {//不同规模的数据int[] dataSize = {1000000, 10000000};for (int n : dataSize) {//准备用于查找的数组Integer[] data = ArrayGenerator.generateOrderedArray(n);//nanoTime()方法返回的其实是一个时间戳,// 是一个长整型,当前用纳秒计算的话时间戳long startTime = System.nanoTime();//对于每个规模的数据,可以通过增加查找次数来达到扩大时间规模的目的/*因为直接进行查找特别大的规模的数据,比如1亿个数据,尤其我们需要的是连续空间,在一般的计算机上可能也会费一点劲,我们通过多做几回,对100万个数据进行100次查找,时间也会相对稳定一些*/for (int k = 0; k < 100; k++) {LinearSearchGenerator.search(data, n);}long endTime = System.nanoTime();//endTime - startTime的值就是两个时间戳之间的线性查找所用的时间,单位是纳秒//纳秒与秒之间是10^9//对于结果可以是一个浮点数,所以除以1000000000.0double time = (endTime - startTime) / 1000000000.0;System.out.println("n = " + n + ", 100runs: " + time + " s");}}
}
  • 直接将不同规模的数据存放在数组中
    • int[] dataSize = {1000000, 10000000};
  • 对于每个规模的数据,可以通过增加查找次数来达到扩大时间规模的目的
    • 因为直接进行查找特别大的规模的数据,比如1亿个数据,尤其我们需要的是连续空间,在一般的计算机上可能也会费一点劲,我们通过多做几回,对100万个数据进行100次查找,时间也会相对稳定一些
    • 并且多次测量就有多组数据,可以进行统计分析,计算平均值、标准差等
for (int k = 0; k < 100; k++) {LinearSearchGenerator.search(data, n);
}
  • 对于1000000和10000000这两个规模的数据,分别执行查找100次,最后的结果如下:
    • 消耗时间也与硬件有关,所以每次时间都不相同
      在这里插入图片描述
  • 从运行结果中,可以看到,对于100万级别的数据,进行100次的查询,大概是0.13s的时间,对于1000万级别,大概是0.7s的时间
    • 0.7大概是0.13的5倍(其实有时候是6倍以上甚至10倍,这与计算机的性能有关),而我们第一次的数据规模是第二次的10倍
    • 从侧面证明了线性查找法的时间复杂度是 O ( n ) O(n) O(n)级别的,时间性能和数据规模之间是线性关系
    • 时间复杂度描述的是随着n的增长相应的算法的性能增长的趋势其实就是这个意思

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

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

相关文章

多种内网穿透的实现方案

1. 内网穿透的应用场景 1.1. 开发调试 比如企业微信、钉钉等开发&#xff0c;需要一个回调地址&#xff0c;开发的时候&#xff0c;希望回调到开发的电脑上&#xff0c;打断点进行调试&#xff0c;这就需要穿透到内网的开发机器。 1.2. 演示测试 有需要演示或测试的系统&am…

SLAM论文速递:SLAM—— MID-Fusion:基于八叉树的对象级多实例动态SLAM—4.26(1)

论文信息 题目&#xff1a; MID-Fusion:Octree-based Object-Level Multi-Instance Dynamic SLAMMID-Fusion:基于八叉树的对象级多实例动态SLAM 论文地址&#xff1a; https://ieeexplore.ieee.org/abstract/document/8794371发表期刊&#xff1a; 2019 International Conf…

凌恩生物文献分享|一株细菌完成图也能发一区10分+!

期刊&#xff1a;Science of the Total Environment 影响因子&#xff1a;10.753 发表时间&#xff1a;2022 样本类型&#xff1a;Bosea sp. Ads-6菌株 客户单位&#xff1a;中国科学院微生物研究所 一、研究背景 环境中抗生素残留和耐药性的增加引发了许多…

亚马逊美国站纽扣电池标准

近日&#xff0c;亚马逊美国站公布要求卖家需遵守扭电池和硬币电池的新包装和警示标签规定公告。 在亚马逊销售单独的纽扣电池和硬币电池&#xff0c;则从2023年3月2日开始&#xff0c;您需要证明您的符合儿童安全包装和警告标签要求。 适用产品有;单独的纽扣电池或硬币电池&a…

Android SeekBar控制视频播放进度(二)——seekTo()不准确

Android SeekBar控制视频播放进度二——seekTo不准确 简介seekTo()视频帧 和 视频关键帧解决办法方法一方法二 简介 上一篇文章中&#xff0c;我们介绍了使用SeekBar控制视频播放&#xff0c;使用过程中发现&#xff0c;对于一些视频&#xff0c;我们拖动SeekBar进度条调节播放…

谈谈如何用开源网关进行 API 管理

需求痛点 1.企业不清楚到底有多少个API&#xff0c;无法形成API资产管理等问题。 2.API在不同集群的生命周期问题。 3.API运行状态监控和告警问题。 4.API请求限流、流量控制以及安全等问题。 功能介绍 Apinto的API管理提供API生命周期控制&#xff1a;可管理所有API&…

【DRF配置管理】如何在视图类使用get_objects()

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 DRF应用和管理 【DRF配置管理】Django使用DRF框架 【DRF配置管理】如何在视图类配置参数(一) 【DRF配置管理】如何在视图类配置参数(二) 【DRF配置管理…

跨数据中心下的 Kafka 高可用架构分析

导语 本文介绍了 Kafka 跨数据中心的两种部署方式&#xff0c;简要分析两种方式下的不同架构以及优缺点&#xff0c;对这些架构可能碰到的问题也提供了一些解决思路&#xff1b;同时也说明了 Kafka 跨数据中心部署的社区解决方案和商业化解决方案。 背景 Kafka 作为世界上最…

Excel技能之实用技巧,高手私藏

今天来讲一下Excel技巧&#xff0c;工作常用&#xff0c;高手私藏。能帮到你是我最大的荣幸。 与其加班熬夜赶进度&#xff0c;不如下班学习提效率。能力有成长&#xff0c;效率提上去&#xff0c;自然不用加班。 消化吸收&#xff0c;工作中立马使用&#xff0c;感觉真不错。…

宠物领养系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87708775 更多系统资源库…

「OceanBase 4.1 体验」|大厂开始接入的国产分布式数据库,不来了解了解?

OceanBase 4.1 体验 前言OCP Express在线升级功能租户级物理备库TP&#xff08;事务处理&#xff09;和AP&#xff08;分析处理&#xff09;优化TP 性能优化AP 性能优化 结尾 前言 上次我们讲了本人自己亲自上手OceanBase 4.1的初体验&#xff0c;国产的分布式数据库也太太太太…

【STM32】基础知识 第八课 MDK 工程

【STM32】基础知识 第八课 MDK 工程 准备工作新建寄存器版本 MDK 工程步骤新建工程文件夹添加文件魔术棒设置绝对路径和相对路径对比测试程序 新建 HAL 库版本 MDK 工程CMSISHAL 库简介DriversMiddlewaresDevice 和 Include HAL 库文件介绍HAL 库 API 函数和比那辆命名规则HAL …

【ArcGIS】常见问题总结

1 arcgis如何打开*.adf文件 在处理数据时发现&#xff0c;获取到的土地利用类型数据有两个文件夹&#xff0c;一个叫info&#xff0c;另一个叫lucc2010&#xff08;年份&#xff09;&#xff0c;打开lucc2010里面是一系列的*.adf文件&#xff0c;数据应该如何打开呢&#xff1…

【Vue】Vue 前端设计模式梳理

文章目录 一、什么是设计模式&#xff1f;二、设计几个原则三、常见的设计模式及实际案例【1】单例模式1. 什么是单例模式&#xff1f;2.Vue中的单例模式 【2】工厂模式1. 什么是工厂模式&#xff1f;2.Vue中的工厂模式 【3】策略模式1. 什么是策略模式&#xff1f;2.策略模式的…

QT笔记——QtPropertyBrowser的使用

上一节&#xff0c;我们将了如何去配置QtPropertyBrowser 本节&#xff0c;我们将说明 如何 去 使用QtPropertyBrowser 这个属性类的一些基本知识 简单的几种用法&#xff1a; 首先&#xff1a; 我们需要创建一个Widget 提升一个类 为 QtTreePropertyBrowser .h文件 QtVariant…

详解客户关系管理系统

一、客户关系管理系统的重要性 客户关系管理系统&#xff0c;是指利用软件、硬件和网络技术&#xff0c;为企业建立一个客户信息收集、管理、分析和利用的信息系统。以客户数据的管理为核心&#xff0c;记录企业在市场营销和销售过程中和客户发生的各种交互行为&#xff0c;以…

华为C++研发工程师编程题 ACM模式输入输出|| 1.汽水瓶,2.明明的随机数,3.进制转换

C ACM输入输出 1.汽水瓶题目描述思路代码如下 2.明明的随机数题目描述思路&#xff1a;代码如下&#xff1a; 3.进制转换题目描述思路&#xff1a;代码如下 题目链接&#xff1a; 华为研发工程师编程题 1.汽水瓶 题目描述 某商店规定&#xff1a;三个空汽水瓶可以换一瓶汽水…

服务器空间不足处理与解决思路—实战docker占用空间太大

前言 服务器Centos操作系统&#xff0c;空间不足的问题处理了三次了&#xff0c;决定把它的解决思路和处理过程记录下来。服务器空间不足是一个经常会遇到的问题&#xff0c;尤其是在大型应用程序和网站上。当服务器空间不足时&#xff0c;应该采取一些步骤来处理和解决这个问…

LeetCode:206. 反转链表

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340; 算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;206. 反转链表 题目描述&#xff1a;给你单链表的头节点 head &#x…

html学习(布局方式(layout)、浮动(float)、定位(position)、弹性盒(flex))

布局方式(layout) 文档流 文档流&#xff08;normal flow&#xff09; 文档流通俗的讲&#xff0c;就是一个web页面中&#xff0c;每一个模块只能从上到下从左往右的方式排列在页面上。 将窗口自下而上分成一行一行&#xff0c;应在每行中按从左至右的依次排放元素&#xff0…