怎样测试程序的平均性能

简介: 标准库中的sort函数,是快速排序算法的典型实现。算法将含有n个元素的序列排序,平均需要 O(n log n) 时间。

标准库中的sort函数,是快速排序算法的典型实现。算法将含有n个元素的序列排序,平均需要 O(n log n) 时间。


上周,我提出了“测试一个程序的性能比测试其功能更难”这个观点。确认程序的性能达到标准以及确定“标准”的含义都十分困难。


接下来,我会继续讨论标准库中的sort(排序)函数。sort函数实现了快速排序算法,快速排序算法平均可以在 O(n log n) 时间内对含有n个元素的序列进行排序。除了这个平均性能之外,如果选择了“不幸”的输入情况,快速排序的运行时间会比平均时间长很多,比如,某些情况下快速排序的时间复杂度可以达到O(n2)。我使用“不幸”这个词是因为在快速排序的实现中经常使用随机性的来保证O(n2)这样的性能表现很少出现。


为什么随机性在这里很重要呢?快速排序算法开始时挑选序列中的一个特定元素开始排序,叫做pivot(中心数据)。然后,快速排序算法调整元素的顺序,使得小于等于中心数据的元素位于中心数据的前面,所有大于中心数据的元素排在中心数据的后面。最后,快速排序算法递归调用,来完成对这两部分元素的排序


因此,快速排序的执行时间,最坏情况下与元素个数对应的最大递归深度成比例。在实现中,依赖于递归深度的快速排序的性能,一般不会大于O(log n)。只要中心数据选定,递归深度就可以估计。平均情况下,这个深度与最大或最小元素的值无关。


快速排序算法是怎样确保选定的中心数据不是很接近序列的端点呢?一般来看,这是无法保证的。尽管如此,大部分情况下可以采用随机选取中心数据的方法,来避免出现最坏情况。这样做可以保证快速排序算法的平均性能是可以接受的,即使在个别情况下,中心数据会出现在序列的端点位置,从而导致算法性能低下。由于这样的情况非常少见,对于平均性能来说它不是一个大问题。对吗?


这要视情况而定。假设,你的任务是编写性能测试程序,来测试快速排序的实现。

你怎样将c++标准中模糊的“平均性能”,改写为实际需求,从而可以测试所有情况?

你以怎样的方式来测试快速排序,这样的方式可以保证测试结果正确可靠?


测试平均性能之所以困难,是因为在这个概念中一个概率的因素。如果,程序最终必须产生一个特定结果,那么,你可以确定一个测试程序的运行结果是正确还是错误。相反,如果你在测试平均性能,那么对于一个单独的测试用例,无法判断运行结果是否正确。最好情况是,通过运行越来越多的测试用例,你可以更有把握程序是否正确运行。在这个测试的过程中,更多的测试可能会改变你对于程序正确性的判断。


简而言之,如果性能中包括了关于平均执行时间的描述,那么相应的测试需要用到一些统计分析。这样的分析并不简单,但是这是工程应用的传统。美国航空191号班机的空难就是一个例子。191号班机在1979年5月25日从奥黑尔国际机场起飞。当飞机刚刚离开地面时,飞机左翼引擎忽然失灵并且从机翼上脱落。引擎是通过安全销连接在机翼上的,这样的设计是为了与机翼脱离而不是毁坏机翼。尽管如此,由于维护失误,机翼被毁,导致飞机失控,发生空难,机上所有人无一幸免。


在阅读相关的调查中,我看见了不同的飞机制造商对安全销进行的测试,证明— 假设飞机正常维护 — 安全销会使得引擎离开机翼而不是毁坏机翼。在此之前,我没有见到过这样的测试,但是设计安全销在工程商的主要问题是:安全销的目的是,受到过大压力时,使引擎和机翼脱落。没有办法在安全销不被破坏的情况下测试安全销是否满足要求。因此,在飞机中实际使用的安全销不能检测。


人们怎样才能确保使用这样生产的安全销不会影响飞机的安全性呢?答案设计非常聪明。

引擎被许多个安全销固定在机翼上,这样即使有一个安全销失灵,引擎也能从机翼上分离,而不损坏机翼。


安全销以100个为一批进行生产,一个批次内的安全销同时以同样的方式生产制造。

每个批次的100个安全销中,会被随机挑选10个进行测试,因此,10个安全销会在测试中毁坏。如果,10个安全销都通过了测试,那么就认为剩下的90个安全销是安全可用的。如果10个中有一个安全销没有通过测试,那么这个批次都会被销毁。


显然,这样的设计不仅仅包括了巧妙的工业设计,也包含了精妙的统计分析。必须准确选择对安全销的限制条件,在10%的安全销已经通过测试的条件下,即使两个随机选取的安全销也几乎不可能超出限制条件。我推测,这样的限制条件可能是比实际应用中安全销需要满足的限制条件更窄的范围。


我不想为了评估快速排序算法的平均性能而进行这样的统计分析。即使我有信心可以正确地进行类似的统计分析,将来可能出现的规范或者测试程序的改变,都会使这样的分析无效。同时,在以快速排序为例的算法,和以安全销为例的机械设备之间有一个重要区别,那就是,有时为了达到某些目的,算法的输入会被设计的非常复杂。比如在Doug McIlroy 1999年写的论文中,详细描述了怎样构造快速排序的输入,使得算法对于n个元素的排序时间达到O(n2)。在这样的情况下,快速算法就与描述不符了吗?如果是这样,那么就很难看见我们现在对快速算法的应用了。


使得这样的性能测试问题简单化的一个方法是采用白盒测试的方法。白盒测试的方法利用了已知程序实现细节这一优势。下周,我会详细介绍这样的测试技术

相关文章
|
4天前
|
网络协议 安全 测试技术
性能工具之emqtt-bench BenchMark 测试示例
【4月更文挑战第19天】在前面两篇文章中介绍了emqtt-bench工具和MQTT的入门压测,本文示例 emqtt_bench 对 MQTT Broker 做 Beachmark 测试,让大家对 MQTT消息中间 BenchMark 测试有个整体了解,方便平常在压测工作查阅。
133 7
性能工具之emqtt-bench BenchMark 测试示例
|
4天前
|
设计模式 测试技术 持续交付
深入白盒测试:提升软件质量与性能的关键策略
【4月更文挑战第20天】 在软件开发的复杂世界中,确保产品的质量和性能始终是至关重要的任务。白盒测试,作为软件测试领域的重要分支,提供了对程序内部结构和逻辑的深入分析手段。本文将探讨如何通过有效的白盒测试策略来优化软件性能,减少缺陷,并最终提高用户满意度。通过剖析代码检查、单元测试、集成测试等白盒测试技术,我们将了解这些方法如何揭示潜在的问题点,并为改进提供方向。
|
4天前
|
安全 算法 测试技术
深入白盒测试:提升软件质量与性能的关键策略
【4月更文挑战第7天】 在软件开发生命周期中,确保代码的质量和性能至关重要。白盒测试作为一种重要的测试方法,允许测试者通过检查程序内部结构和逻辑来识别缺陷和问题。本文旨在探讨白盒测试的核心原则、技术及其对提升软件产品可靠性的影响。我们将重点分析如何利用白盒测试进行有效的单元测试、集成测试以及系统测试,并讨论现代软件测试工具如何帮助实现自动化测试流程,从而优化开发周期并降低错误率。
|
4天前
|
Linux Android开发
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
14 0
|
4天前
|
存储 监控 Cloud Native
如何通过持续测试和调整来提高OLAP系统的性能和可扩展性?
【5月更文挑战第14天】如何通过持续测试和调整来提高OLAP系统的性能和可扩展性?
13 2
|
4天前
|
NoSQL 测试技术 MongoDB
【MongoDB 专栏】MongoDB 的性能基准测试与评估
【5月更文挑战第11天】MongoDB的性能基准测试对于优化至关重要,涉及数据读写速度、查询响应时间及吞吐量等指标。测试应明确目标和范围,选择合适的工具,考虑数据模型、索引、查询优化和系统配置等因素。性能评估需关注读写吞吐量、响应时间和资源利用率。通过多次测试、逐步增加负载和对比其他系统,识别性能瓶颈并持续优化。随着技术发展,测试方法和工具将持续创新,以应对复杂性能挑战。
【MongoDB 专栏】MongoDB 的性能基准测试与评估
|
4天前
|
算法 测试技术 Linux
LabVIEW NI CompactRIO控制器:性能和吞吐量基准测试
LabVIEW NI CompactRIO控制器:性能和吞吐量基准测试
12 1
|
4天前
|
Linux 测试技术 Windows
LabVIEW对NI Linux RT应用程序性能进行基准测试
LabVIEW对NI Linux RT应用程序性能进行基准测试
|
4天前
|
测试技术
LabVIEW程序测试
LabVIEW程序测试
|
4天前
|
监控 测试技术 持续交付
Python自动化测试代理程序可用性
总之,通过编写测试用例、自动化测试和设置监控系统,您可以确保Python自动化测试代理程序的可用性,并及时发现和解决问题。这有助于提供更可靠和高性能的代理服务。
17 4

热门文章

最新文章