ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Bogus 性能基准测试指南:用 BenchmarkDotNet 量化假数据生成的性能

Bogus 性能基准测试指南:用 BenchmarkDotNet 量化假数据生成的性能 开发工具测试【免费下载链接】Bogus:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.项目地址https://gitcode.com/gh_mirrors/bo/Bogus点击查看免费下载本篇技术指南围绕 Bogus 仓库中的Source/Benchmark基准测试项目展开讲解如何在本仓库环境中编译并以 Release 模式运行 BenchmarkDotNet 基准测试、如何准备 R 环境以生成可视化图表、如何解读内置的各类基准场景对象生成、随机子集、SSN 字符串、随机字符串填充、Randomizer 随机数算法等。读完本文你将掌握在本仓库中复现并扩展性能实验的完整操作流程并能结合 Randomizer.cs 等源码理解每项基准背后的实现原理。Benchmark 项目在 Bogus 仓库中的定位Bogus 是一个面向 C#、F# 与 VB.NET 的假数据生成器项目描述为 A simple fake data generator for C#, F#, and VB.NET基于 faker.js 移植。仓库的解决方案 Bogus.sln 下除了核心库 Bogus 与测试工程 Bogus.Tests 之外还专门保留了一个独立的性能基准工程Source/Benchmark。它的定位非常明确用 BenchmarkDotNet 对 Bogus 的关键代码路径做可复现、可对比的性能测量包括 Faker 对象生成、Randomizer 的随机数/随机子集算法、字符串填充方式等。该项目的使用说明集中在 Source/Benchmark/README.md全篇围绕如何运行基准测试展开涵盖环境要求、编译命令、执行命令、结果输出位置与运行注意事项五个要点。下文将以此为骨架逐节展开并补充仓库源码层面的细节。环境准备.NET SDK 与 R 统计计算环境根据 Source/Benchmark/README.md运行基准测试需要两类前置依赖.NET SDK.NET 3.1 或更高版本。仓库根目录的 global.json 同时约束了 SDK 版本策略而 Benchmark.csproj 将目标框架声明为netstandard2.0并引用BenchmarkDotNet与BenchmarkDotNet.Diagnostics.Windows版本均为 0.12.1以及核心库..\Bogus\Bogus.csproj。这意味着编译产物是一个面向 netstandard2.0 的程序集由 .NET 运行时宿主加载执行。R 统计计算环境R version 3.3.3 即 2017-03-06 版本或更新。R 并非基准测量本身所必需而是 BenchmarkDotNet 的 RPlotExporter 生成性能分布图如密度图、箱线图的绘图后端。README 特别强调必须确保rscript.exe已加入系统 PATH这样基准运行结束后才能自动调用 R 生成图表。这一点与多个基准类上的[RPlotExporter]特性相对应——例如 BenchRandomSubset.cs、BenchSsn.cs、BenchStringFill.cs 都标注了该导出器。提示在 Linux/macOS 环境下对应可执行文件为Rscript同样需要保证其在 PATH 中可被命令行解析到。编译基准工程必须以 Release 模式构建README 明确要求以 Release 模式编译 Benchmark 工程dotnet build -c Release这一步在仓库的构建脚本中也有印证Source/Builder/Build.cs 中 NUKE 构建脚本的CompileTarget 会以Release配置编译整个解决方案且 Benchmark 工程的 csproj 中直接固化了Optimizetrue与ConfigurationRelease两个属性见 Benchmark.csproj。为什么必须用 Release原因在于基准测试的准确性Debug 构建包含调试符号、关闭了 JIT 优化、且可能有额外的边界检查测出的数据无法反映真实生产性能。BenchmarkDotNet 官方也一贯要求在 Release 且无调试器附加的环境下运行。README 中的警告——不要通过 Visual Studio 调试器或 F5 运行这些基准——正是同一个道理调试器会禁用 JIT 优化、干扰计时器使测量结果失真。运行基准测试命令行执行与产物位置编译完成后在命令行中执行README 原文为 Windows 风格的路径$ dotnet benchmark bin\Release\netstandard2.0\Benchmark.dll其中dotnet benchmark是 BenchmarkDotNet 提供的命令行工具入口参数为编译产物的程序集路径。由于 csproj 将 TargetFramework 声明为netstandard2.0Release 构建产物默认落在bin/Release/netstandard2.0/下因此Windows 下路径为bin\Release\netstandard2.0\Benchmark.dllLinux/macOS 下使用斜杠形式bin/Release/netstandard2.0/Benchmark.dll两者指向同一产物。执行后 BenchmarkDotNet 会列出程序集中所有标记了[Benchmark]的方法供你选择可以指定运行其中某一个也可以按序号选择多个或全部。每个基准都会经过预热warmup、多次迭代测量iteration并报告均值、标准差、置信区间等统计量。运行结束后基准结果包括 Markdown 报告与 R 生成的图表会输出到\BenchmarkDotNet.Artifacts目录README 原文使用 Windows 反斜杠写法Unix 系环境对应BenchmarkDotNet.Artifacts子目录。该目录中典型的产物包括.md格式的 Markdown 汇总报告对应[MarkdownExporter]特性见 BenchGenerate.cs 与 PR300_BenchDecimal.cs.csv格式的原始测量数据便于二次分析若安装了 R则由 RPlotExporter 生成.png/.svg图表文件。内置基准场景逐一解析仓库的 Benchmark 工程内置了多组基准类它们分别针对 Bogus 的不同核心路径是理解库内部实现与性能特征的最好教材。以下按文件逐一说明。1. Faker 对象生成开销BenchGenerateBenchGenerate.cs 对比了四种 Faker 配置方式下批量生成 10,000 个Project对象含Id、Name、Description三个属性的成本FakerDefault直接new FakerProject()不设任何规则FakerCustom通过CustomInstantiator(f new Project())指定自定义实例化器FakerWithRules自定义实例化器 一条RuleFor(p p.Id, f f.IndexGlobal)规则FakerWithRulesComplex在上一项基础上追加Name使用f.Person.Company.Name f.UniqueIndex与Descriptionf.Lorem.Paragraphs(3)两条复杂规则。所有 Faker 都通过.UseSeed(1337)固定了随机种子保证测量的是稳定的代码路径而非随机分支。每个方法执行Generate(10_000).ToList()从而把对象实例化、规则委托调用、数据集合查询的总体开销纳入测量。该基准可以直观回答Bogus 生成一条带规则的对象到底比裸new慢多少这类问题。2. 随机子集选取PickRandom vs ShuffleTakeBenchRandomSubset.cs 对比两种从 2000 个元素中随机挑出Selections个不重复元素的方式PickRandom手写的单遍抽样算法类内PickRandomT辅助方法——遍历列表对每个元素以递减的概率决定是否选中期望挑选出恰好amountToPick个ShuffleTake调用Randomizer.Shuffle(items).Take(Selections)即先整体洗牌再截取前 N 个。值得关注的是Shuffle的底层实现在 Randomizer.cs 中ShuffleT首先把输入ToList()缓冲然后使用 Fisher–Yates 洗牌逻辑对缓冲区进行就地交换。也就是说ShuffleTake的开销包含一次完整的拷贝与洗牌而PickRandom是单遍流式抽样。基准通过[Params(2, 10, 100, 500, 1000, 1999)]把抽取数量作为参数变量测量不同选择比例下的性能差异。Randomizer本身位于 Randomizer.cs是 Bogus 所有随机数据的底层入口。3. SSN 字符串生成三种算法对比BenchSsn.cs 针对生成美国社保号SSN格式字符串这一典型场景对比三种实现SsnAlgo1/SsnAlgo2都通过三次r.Int(...)分别生成三段数字前段1..898且跳过 666中段1..99后段1..9999再用插值字符串拼成000-00-0000格式SsnAlgo3改为一次r.Int()取整型随机数然后通过位运算切片(x 22) % 898取前 10 位算首段、x 0x7F取低 7 位算中段、(x 7) 0x3FFF取中间 14 位算末段并对各段为 0 或 666 的边界做 1 修正最终同样格式化输出。该基准展示了一种典型优化思路把多次随机数调用合并为一次大范围随机采样加位运算切分以换取更少的 RNG 调用次数。文件中的注释如 2^10 1024、first 7 bits解释了位掩码的取值来源。4. 随机字符串填充StringBuilder vs char[]BenchStringFill.cs 对比了两种从字符池随机取字符、填充出指定长度字符串的方式FillWithStringBuilder用StringBuilder(TargetLength)预分配容量逐字符AppendFillWithFixedCharArray分配char[TargetLength]数组逐字符赋值后new string(target)一次性构造。两个方法都使用r.Number(0, Pool.Length - 1)取随机下标Randomizer.Number的实现同样在 Randomizer.cs 中字符池固定为 26 个小写字母。[Params(2, 10, 100, 500, 1000, 5000, 20000)]让目标长度横跨 2 到 20000用于观察两种策略在不同长度下的分配与拼接开销是评估 Bogus 内部字符串生成路径例如Randomizer.String()的近似模型。5. PR 优化验证Randomizer 的 Number 与 DecimalPR300 系列基准是典型的为验证 Pull Request 优化而编写的对比实验PR300_BenchRandomNumber.cs在int.MinValue到int.MaxValue的完整范围内比较Number的三种实现——旧实现max1后调Random.Next遇int.MaxValue溢出需特殊处理、基于NextBytes的位拼接方案以及 JDG 方案先用Next(int.MinValue, 0)取负半区再按 50% 概率位取反以覆盖正半区见NumberJDG的注释NumberJDG2则用两次采样各取 16 位拼接成 32 位结果PR300_BenchDecimal.cs对比Randomizer.Decimal()的旧实现与三种 JDG 改进版。改进版的核心思路是decimal类型 128 位中 mantissa 占 96 位先随机填充 96 位得到[0, 7.9228162514264337593543950335]范围内的均匀值再线性映射到调用方要求的[min, max]区间三种变体的差异在于是否使用int[4]数组有分配以及缩放用除法还是乘法DecimalJDGNoAllocMult预先计算1 / 7.9228...为乘法常数见 PR300_BenchDecimal.cs。文件中详细注释了 decimal 的位布局sign、scale、96 位 mantissa可配合 Randomizer.cs 中Decimal/Number的正式实现对照阅读。这两个基准类都标注了[SimpleJob(RuntimeMoniker.NetCoreApp31), SimpleJob(RuntimeMoniker.Net471)]见 PR300_BenchRandomNumber.cs即同时在 .NET Core 3.1 与 .NET Framework 4.7.1 两套运行时上执行测量用于确认优化在两类运行时上的一致收益——这也解释了 README 要求 .NET 3.1 SDK 及以上的原因。扩展你自己的基准若希望在本地复现或扩展这些实验可按以下步骤进行在 Source/Benchmark 目录下新建一个基准类或在现有类中追加方法为方法标注[Benchmark]特性并按需使用[Params]、[GlobalSetup]、[MemoryDiagnoser]、[RPlotExporter]等 BenchmarkDotNet 特性需要测量 GC 分配时在类上添加[MemoryDiagnoser]如 BenchGenerate.cs 所示通过dotnet build -c Release重新编译运行dotnet benchmark并选择目标方法结果与图表在BenchmarkDotNet.Artifacts目录中查看。需要注意的是基准类中被注释掉的[Benchmark]如 BenchGenerate.cs 中的Generate_Default表示当前未纳入测量可自行取消注释参与对比。运行注意事项与常见问题汇总 README 及仓库配置中的关键约束务必 Release 构建Debug 产物会导致数据失真csproj 已固化Optimizetrue与ConfigurationRelease不要用 Visual Studio 调试器或 F5 运行调试器会禁用 JIT 优化并干扰计时README 对此给出明确警告R 环境仅用于绘图若只想看数值结果而不关心图表R 缺失时基准仍可运行只是 RPlotExporter 的图表生成步骤会失败或跳过若要出图需保证rscript.exeWindows/RscriptUnix在 PATH 中运行时选择PR300 系列基准会同时在 .NET Core 3.1 与 .NET Framework 4.7.1 上运行需要对应运行时可用结果目录所有导出物Markdown 报告、CSV 原始数据、R 图表统一落在BenchmarkDotNet.Artifacts目录。小结Source/Benchmark是 Bogus 仓库中一套完整、可独立复现的性能实验台从环境准备.NET SDK R、Release 编译、命令行运行到 BenchmarkDotNet.Artifacts 中的报告与图表流程清晰而BenchGenerate、BenchRandomSubset、BenchSsn、BenchStringFill与 PR300 系列基准则覆盖了 Faker 生成管线与 Randomizer 底层随机算法的关键路径与 Randomizer.cs 的源码实现一一对应。按照本文步骤你可以在本仓库中复现全部内置基准并以此为模板构建属于自己的性能实验。更多关于 BenchmarkDotNet 导出器与图表配置的说明可参考其官方文档README 末尾亦给出了指引。赞分享开发工具测试【免费下载链接】Bogus:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.项目地址https://gitcode.com/gh_mirrors/bo/Bogus点击查看免费下载相关推荐CANN/ops-nn Threshold算子说明Threshold 产品支持情况 | 产品 | 是否支持 | | : | : : | | term Ascend 950PR/Ascend 950DT/te人工智能算子库深度学习CANNAscendPolly 基准测试指南使用 BenchmarkDotNet 测量 .NET 弹性策略与 v8 管线性能Polly 基准测试指南使用 BenchmarkDotNet 测量 .NET 弹性策略与 v8 管线性能 本篇指南围绕 Polly 仓库的 bench/REA后端微服务BenchmarkDotNet 集成 Visual Studio Profiler 实战使用 VSDiagnostics 诊断器捕获基准测试性能数据BenchmarkDotNet 集成 Visual Studio Profiler 实战使用 VSDiagnostics 诊断器捕获基准测试性能数据 本文介绍性能测试开发工具上一篇深度解析Redisson与Quarkus微服务框架的集成实战下一篇为什么选择chart-Go开发者必备的轻量级图表解决方案深度测评创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表