.NET 9 平台下,我们对两种经典的排序算法 MergeSortTest(归并排序)和 QuickSortTest(快速排序)进行了性能基准测试(Benchmark),以评估它们在不同数据规模下的执行效率、内存分配及垃圾回收行为。

测试使用了 BenchmarkDotNet 工具,确保结果具有高度可重复性和统计意义。

  • Datadog.Trace.BenchmarkDotNet

🧪 测试环境

  • 运行时(Runtime):.NET 9.0.6 (X64 RyuJIT AVX2)
  • 操作系统:Windows 11 24H2(开发预览版)
  • SDK 版本:.NET SDK 9.0.301
  • 测试工具:BenchmarkDotNet v0.15.2
  • 测试参数:
    • 数据量 N = 100, 1000, 10000(分别模拟小、中、大数据集)

项目准备

创建项目

使用 .net cli 创建控制台项目,执行如下命令:

dotnet new console -n SortTest
cd SortTest# 安装 nuget 包 Datadog.Trace.BenchmarkDotNet
dotnet add package Datadog.Trace.BenchmarkDotNet

控制台项目 SortTest.csproj 信息如下:

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net9.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable><PublishAot>true</PublishAot><InvariantGlobalization>true</InvariantGlobalization></PropertyGroup><ItemGroup><PackageReference Include="Datadog.Trace.BenchmarkDotNet" Version="2.61.0" /></ItemGroup></Project>

排序算法实现

  • 归并排序
// =============================
// 排序算法实现:归并排序
// =============================namespace SortTest;public class MergeSort
{public static void Sort(int[] array){if (array.Length <= 1) return;int mid = array.Length / 2;int[] left = array[..mid];int[] right = array[mid..];Sort(left);Sort(right);Merge(array, left, right);}private static void Merge(int[] result, int[] left, int[] right){int i = 0, j = 0, k = 0;while (i < left.Length && j < right.Length){if (left[i] <= right[j])result[k++] = left[i++];elseresult[k++] = right[j++];}while (i < left.Length)result[k++] = left[i++];while (j < right.Length)result[k++] = right[j++];}
}
  • 快速排序
// =============================
// 排序算法实现:快速排序
// =============================namespace SortTest;public class QuickSort
{public static void Sort(int[] array, int low, int high){if (low < high){int pivotIndex = Partition(array, low, high);Sort(array, low, pivotIndex - 1);Sort(array, pivotIndex + 1, high);}}private static int Partition(int[] array, int low, int high){int pivot = array[high];int i = low - 1;for (int j = low; j < high; j++){if (array[j] <= pivot){i++;Swap(array, i, j);}}Swap(array, i + 1, high);return i + 1;}private static void Swap(int[] array, int i, int j){if (i != j){int temp = array[i];array[i] = array[j];array[j] = temp;}}
}

添加测试基准

  • Benchmark 测试类
// =============================
// Benchmark 测试类
// =============================using BenchmarkDotNet.Attributes;
using Datadog.Trace.BenchmarkDotNet;namespace SortTest;[DatadogDiagnoser]
[MemoryDiagnoser]
public class SortingBenchmark
{private int[] data = [];[Params(100, 1000, 10000)] // 不同数据规模public int N;[GlobalSetup]public void Setup(){var random = new Random(42); // 固定种子以保证重复性data = Enumerable.Range(0, N).Select(_ => random.Next(0, N)).ToArray();}[Benchmark]public void MergeSortTest(){var copy = (int[])data.Clone();MergeSort.Sort(copy);}[Benchmark]public void QuickSortTest(){var copy = (int[])data.Clone();QuickSort.Sort(copy, 0, copy.Length - 1);}
}

使用基准测试

Program.cs 添加如下代码:

using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running;
using Datadog.Trace.BenchmarkDotNet;namespace SortTest;internal class Program
{static void Main(string[] args){Console.WriteLine("Hello, SortingBenchmark!");var config = DefaultConfig.Instance.WithDatadog();BenchmarkRunner.Run<SortingBenchmark>(config);}
}

启动项目基准测试,使用 pwsh 执行如下命令:

dotnet run -c Release

下面这些文本信息是使用 BenchmarkDotNet 工具对两种排序算法(MergeSortTestQuickSortTest)进行性能测试后生成的报告。


SortTest.SortingBenchmark-20250705-183953

BenchmarkDotNet v0.15.2, Windows 11 (10.0.26100.4484/24H2/2024Update/HudsonValley)
Unknown processor
.NET SDK 9.0.301[Host]     : .NET 9.0.6 (9.0.625.26613), X64 AOT AVX2DefaultJob : .NET 9.0.6 (9.0.625.26613), X64 RyuJIT AVX2
Method NMean ErrorStdDevGen0Gen1Allocated
MergeSortTest1004.508 μs0.0857 μs0.1863 μs5.3635-8424 B
QuickSortTest1001.249 μs0.0248 μs0.0331 μs0.2689-424 B
MergeSortTest100079.005 μs1.5793 μs2.1083 μs61.4014-96328 B
QuickSortTest100039.192 μs0.6847 μs0.6404 μs2.5024-4024 B
MergeSortTest100001,073.318 μs20.7670 μs26.2637 μs539.0625128.90631112040 B
QuickSortTest10000600.722 μs7.9013 μs6.5980 μs24.4141-40024 B

以下是关键内容的通俗解释:

📊 测试目标

对两种排序算法在不同数据量下的性能进行对比分析,包括:

  • 执行时间(Mean)
  • 内存分配(Allocated)
  • 垃圾回收情况(Gen0, Gen1)

测试分别在以下数据规模下运行:

  • N = 100
  • N = 1000
  • N = 10000

🧪 性能对比结果

方法数据量 (N)平均耗时内存分配GC 次数 (Gen0)
MergeSortTest1004.508 μs8424 B5.3635
QuickSortTest1001.249 μs424 B0.2689
MergeSortTest100079.005 μs96328 B61.4014
QuickSortTest100039.192 μs4024 B2.5024
MergeSortTest100001073.318 μs1112040 B539.0625
QuickSortTest10000600.722 μs40024 B24.4141

✅ 结论:

  • QuickSortTest 的平均耗时和内存占用都明显低于 MergeSortTest
  • 随着数据量增加,两者的差距也越来越大
  • QuickSortTest 在性能和资源消耗方面更优

⚠️ 警告与提示

📌 多峰分布警告(Multimodal Distribution)

  • MergeSortTest 的部分测试结果显示为多峰分布(mValue = 3.23),说明其运行时间波动较大,可能受外部因素影响。

📌 异常值(Outliers)

  • 报告中指出某些测试存在异常值并已被剔除:
    • MergeSortTest: 移除了 4 个异常值
    • QuickSortTest: 不同数据规模下检测到多个异常值并移除

📋 统计指标含义简述

指标名含义解释
Mean平均执行时间
Error置信区间的一半(99.9% 置信度)
StdDev标准差,反映数据波动程度
Gen0 / Gen1垃圾回收次数(代数0/1)
Allocated单次操作分配的内存大小
Median中位数,排除极端值后的中间值
Min / Max最小值和最大值

🖼️ 直方图(Histogram)

每组测试后都有一个简单的直方图,用字符 @ 表示不同时间段内执行次数的分布,帮助可视化执行时间的集中趋势。


📈 小结

  • QuickSortTest 在所有测试中表现更优
    • 更快的执行速度
    • 更少的内存分配
    • 更低的垃圾回收压力
  • MergeSortTest 性能较差且波动较大
    • 特别是在大数据量(N=10000)时表现不佳
    • 存在较多异常值,稳定性不如 QuickSort

如果你希望进一步优化 MergeSort 或想了解为何它表现不佳,可以结合代码逻辑、递归深度、内存使用等因素进行深入分析。

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

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

相关文章

RabbitMQ - SpringAMQP及Work模型

一、概述RabbitMQ是一个流行的开源消息代理&#xff0c;支持多种消息传递协议。它通常用于实现异步通信、解耦系统组件和分布式任务处理。Spring AMQP是Spring框架下的一个子项目&#xff0c;提供了对RabbitMQ的便捷访问和操作。本文将详细介绍RabbitMQ的工作模型&#xff08;W…

微信小程序51~60

1.界面交互-loading提示框 loading提示框用于增加用户体验&#xff0c; 对应的API有两个&#xff1a; wx.showLoading()显示loading提示框wx.hideLoading()关闭loading提示框 Page({getData () {//显示loading提示框wx.showLoading({//提示内容不会自动换行&#xff0c;多出来的…

SqueezeBERT:计算机视觉能为自然语言处理在高效神经网络方面带来哪些启示?

摘要 人类每天阅读和撰写数千亿条消息。得益于大规模数据集、高性能计算系统和更优的神经网络模型&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术在理解、校对和组织这些消息方面取得了显著进展。因此&#xff0c;将 NLP 部署于各类应用中&#xff0c;以帮助网页用…

Springboot开发常见注解一览

注解用法常用参数Configuration用于标记类为配置类&#xff0c;其中通过Bean方法定义Spring管理的组件。它替代XML配置&#xff0c;用Java代码声明对象创建逻辑&#xff0c;并确保单例等容器特性生效。相当于给Spring提供一个“制造说明书”来组装应用部件RestControllerRestCo…

Maven高级——分模块设计与开发

目录 ​编辑 分模块设计与开发 拆分策略 继承与聚合 版本锁定 聚合 作用 实现 Maven中继承与聚合的联系与区别&#xff1f; 联系 区别 私服 分模块设计与开发 将一个大项目拆分成若干个子模块&#xff0c;方便项目的管理维护&#xff0c;扩展&#xff0c;也方便模…

线程池的七个参数设计源于对高并发场景下资源管理、系统稳定性与性能平衡的深刻洞察

⚙️ 一、核心参数设计目标与解决的问题 参数设计目标解决的核心问题典型取值策略corePoolSize&#xff08;核心线程数&#xff09;维持常备线程资源避免频繁创建/销毁线程的开销&#xff0c;提高响应速度CPU密集型&#xff1a;N_cpu 1 IO密集型&#xff1a;2 N_cpu maximum…

少样本学习在计算机视觉中的应用:原理、挑战与最新突破

在深度学习的黄金时代&#xff0c;大量标注数据似乎成了算法性能的前提。然而在许多现实场景中&#xff0c;如医疗图像分析、工业缺陷检测、遥感识别、甚至个性化视觉服务中&#xff0c;高质量、成规模的标注数据往往昂贵、稀缺&#xff0c;甚至难以获得。这种场景正是**少样本…

github在线图床

github做的图床&#xff0c;原理是利用github API实现的在线上传&#xff0c;就一个页面&#xff0c;css和js都是集成在页面&#xff0c;相关信息保存在浏览器缓存中&#xff0c;配置一下即可使用 效果演示&#xff1a; github在线图床 打开网站填写下列信息 github用户名&a…

css-多条记录,自动换行与自动并行布局及gap兼容

实现这样的内容布局&#xff0c;当一段文案长度超过当前行的时候自动占据一行&#xff0c;其他相近的不超过一行自动放在一行间隔隔开 关键实现原理&#xff1a; 弹性布局容器&#xff1a; .history-container {display: flex;flex-wrap: wrap;gap: 12px; }使用flex-wrap: wr…

Redis 哨兵模式部署--docker版本

redis sentinel 简介 Redis Sentinel 是 Redis 官方提供的高可用&#xff08;HA&#xff09;解决方案&#xff0c;用于监控主从架构中的故障并自动完成故障转移。当主节点&#xff08;Master&#xff09;宕机时&#xff0c;Sentinel 能自动选举新的主节点&#xff0c;通知从节…

Java线程中的守护线程

Java线程中的守护线程在Java中&#xff0c;守护线程&#xff08;Daemon Thread&#xff09;是一种特殊类型的线程&#xff0c;它在后台运行&#xff0c;主要用于支持其他线程&#xff08;如用户线程&#xff09;的工作。守护线程不会阻止JVM&#xff08;Java虚拟机&#xff09;…

Flink-状态恢复-isRestore分析

isRestored 方法返回值依赖 restoredCheckpointId 是否为空&#xff1a;restoredCheckpointId 在算子状态句柄&#xff08;StreamOperatorStateHandler&#xff09;中从 StreamOperatorStateContext 获取并赋值给 StateInitializationContext&#xff08;该 context 就是 initi…

rk3128 emmc显示剩余容量为0

机器emmc 容量显示异常&#xff0c;显示剩余容量为0&#xff0c;这时候做了一个让 系统不检测GPP分区部分的操作&#xff0c;此问题才得以解决&#xff0c;如下&#xff1a; system/vold/DirectVolume.cpp -33,6 33,8 #include "VolumeManager.h"#include "Re…

WebAssembly国际化多语种支持

icu linux数据裁剪 先linux编译出所有的工具 mkdir build && cd build ../configure --prefix=$(pwd)/build_wasm/install --enable-static --disable-shared --with-data-packaging=static --enable-tools=yes --enable-extras=yes --e…

Ubuntu 安装 etcd 与 etcd-cpp-apiv3

目录 安装 etcd 安装 etcd-cpp-apiv3 安装 etcd sudo apt update sudo apt install etcd-server sudo apt install -y etcd-client 在 /etc/default/etcd 配置文件中配置&#xff0c;下面示例是单个服务器内进程之间交换信息且只有一个etcd节点。 #节点名称&#xff0c;默认为…

Spring Boot 集成 GeoTools 详解

目录 一、概述二、集成优势三、集成步骤四、使用场景五、案例&#xff1a;周边设施查询系统六、注意事项七、总结 一、概述 什么是 Spring Boot&#xff1f; Spring Boot 是由 Pivotal 团队开发的基于 Spring 框架的快速开发工具&#xff0c;它通过自动配置、起步依赖等特性简…

基础知识:mysql-connector-j依赖

mysql-connector-j 是 MySQL 官方提供的 Java 数据库连接驱动&#xff08;JDBC Driver&#xff09;&#xff0c;用于在 Java 应用程序中连接和操作 MySQL 数据库。它是 MySQL 8.0 版本之后的标准驱动名称&#xff0c;替代了旧的 mysql-connector-java。 一、新旧版本对比 驱动…

vscode remote-ssh 拓展免密访问 linux虚拟机

前置步骤&#xff0c;在linux安装好ssh并且win可以使用密码登录linux sudo apt install openssh-server -y 在win上检查密钥是否存在 检查公钥和私钥cat ~/.ssh/id_rsa.pubcat ~/.ssh/id_rsa 如果不存在&#xff0c;重新生成 ssh-keygen -t rsa -b 4096 重新执行 cat ~/.ssh/…

动手学深度学习-学习笔记【二】(基础知识)

文章目录 1、概述2、课程学习2.1、深度学习介绍2.2、安装2.3、数据操作2.4、数据预处理2.5、线性代数2.6、微积分2.7、自动微分2.8、概率2.8.1、基本概率论2.8.2、处理多个随机变量2.8.3、期望和方差 2.9、查阅文档 1、概述 本篇博客用来记录我学习深度学习的学习笔记&#xf…

瑞盟MS4554N/MS4554N1双向电平转换器重新定义混合电压系统连接

在电子设备的“心脏”——电路系统里&#xff0c;不同功能模块常因性能需求差异&#xff0c;采用差异化的供电电压&#xff1a;传感器用1.8V低功耗运行&#xff0c;主控芯片选3.3V高效处理&#xff0c;传统接口保留5V稳定传输……当这些“电压孤岛”需要互联时&#xff0c;一个…