frontpage如何做网站,外贸网站制作价格表,建行电子银行网上银行,企业管理软件代理微基准测试 r介绍 作为一个行业#xff0c;我们正在采用更高的透明度和更可预测的构建过程#xff0c;以降低构建软件的风险。 持续交付的核心原则之一是通过反馈循环收集反馈。 在Dev9中 #xff0c;我们采用了与CD原则一致的“ 先知道 ”原则#xff0c;这意味着我们我们正在采用更高的透明度和更可预测的构建过程以降低构建软件的风险。 持续交付的核心原则之一是通过反馈循环收集反馈。 在Dev9中 我们采用了与CD原则一致的“ 先知道 ”原则这意味着我们开发团队希望成为第一个知道何时出现故障性能下降或任何与之不符的结果的人。业务目标。 Maven和其他构建工具为开发人员提供了标准化的工具和生态系统可在其中建立和交流反馈。 虽然单元测试功能构建验收数据库迁移性能测试和代码分析工具已成为开发流程中的主要内容但基准测试基本上仍处于过程之外。 这可能是由于缺乏开源的低成本的工具或轻量级的库这些库增加了最小的复杂性。 现有的工具通常需要将外部工具与运行时工件集成在一起从而使复杂性更加复杂并且测试未保存在同一源存储库中甚至没有存储在源存储库中。 本地开发人员无法毫不费力地运行基准测试因此测试会很快失去其价值。 除了主流的解决方案问题外基准测试通常不是在课堂上讲授的并且通常在没有必要的隔离才能获得可靠结果的情况下实施。 这使得所有有关基准测试结果的博客或帖子成为巨魔的成熟目标。 综上所述围绕代码库的关键区域进行某种基准覆盖仍然很重要。 积累有关代码关键部分的历史知识可以帮助影响优化工作向团队通报技术欠债在性能阈值更改已提交时发出警报并比较算法的先前版本或新版本。 现在的问题是如何找到基准并轻松添加到我的新项目或现有项目中。 在此博客中我们将专注于Java项目1.7。 该示例代码将利用Maven尽管Gradle的工作原理非常相似。 我在整个博客中提出了一些建议这些建议是基于过去项目的经验得出的。 JHM简介 在对基准Java代码进行基准测试时有很多强大的选择但是它们大多数都有缺点包括许可证费用额外的工具字节代码操纵和/或Java代理使用非基于Java的代码概述的测试以及高度复杂的配置设置。 我喜欢使测试尽可能接近被测代码以减少脆性降低内聚力并减少耦合。 我认为我以前使用过的大多数基准测试解决方案太麻烦了或者运行测试的代码不够孤立完全集成在代码中或者包含在远离源代码的辅助解决方案中。 该博客的目的是演示如何在构建管道中添加轻量级基准测试工具因此我将不详细介绍如何使用JMH以下博客是学习的绝佳资源 http://jmhwiki.blogspot.com http://java-performance.info/jmh/ http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/ 基准测试模式 关于模式和评分我想指出一小部分因为它们在基本配置的设置中起着重要的作用。 在基本级别上JMH有两种主要的度量类型吞吐量和基于时间的度量。 吞吐量测量 吞吐量是每单位时间可以完成的操作量。 随着框架增加测试的负载量JMH会维护成功和失败操作的集合。 注意确保方法或测试完全隔离并且诸如测试对象创建之类的依赖项是在方法之外或在设置方法中进行预测试的。 使用“吞吐量”该值越高越好因为它表明可以在单位时间内运行更多的操作。 基于时间的测量 基于时间的测量是吞吐量的反伙伴。 基于时间的测量的目标是确定特定操作每单位时间运行多长时间。 平均时间 最常见的基于时间的度量是“ AverageTime”用于计算操作的平均时间。 JMH还将产生“ 得分错误 ”以帮助确定对产生得分的信心。 “ 得分误差 ”通常是置信区间的1/2它表示结果与平均时间的偏离程度。 结果越低表明每次操作的平均运行时间越短越好。 采样时间 SampleTime与AverageTime相似但是JMH尝试增加更多的负载并查找失败从而产生失败百分比矩阵。 使用AverageTime时数字越小越好这些百分比对于确定由于吞吐量和时间长度而导致失败的位置很有用。 SingleShotTime 最后也是最不常用的模式是SingleShotTime。 该模式实际上是一次运行可用于冷测方法或测试您的测试。 如果在运行基准测试时作为参数传递SingleShotTime可能会很有用但会减少运行测试所需的时间尽管这样做会减少测试的价值并可能使它们自重。 与其他基于时间的测量一样值越低越好。 将JMH添加到Java项目 目标本部分将显示如何创建可重复使用的工具该工具可在不增加代码开销或代码重复的情况下添加新测试。 注意依赖项在“测试”范围内以避免将JMH添加到最终工件中。 我创建了一个在使用Protobuf替代REST for Microservices时使用JMH的github存储库。 可以在这里找到代码 https : //github.com/mike-ensor/protobuf-serialization 1首先将依赖项添加到项目中 dependencies
!-- Other libraries left out for brevity --
!-- jmh.version is the lastest version of JMH. Find by visitinghttp://search.maven.org --dependencygroupIdorg.openjdk.jmh/groupIdartifactIdjmh-core/artifactIdversion${jmh.version}/versionscopetest/scope/dependencydependencygroupIdorg.openjdk.jmh/groupIdartifactIdjmh-generator-annprocess/artifactIdversion${jmh.version}/versionscopetest/scope/dependency
!-- Other libraries left out for brevity --
/dependencies 2JMH建议将基准测试和工件包装在同一uber jar中。 有几种方法可以实现uber jar显式地使用made的“ shade”插件或隐式地使用Spring BootDropwizard或具有类似结果的某些框架。 出于本博客文章的目的我使用了Spring Boot应用程序。 3添加具有主条目类和全局配置的测试工具。 在此步骤中在项目的测试区域中创建一个入口点用1表示。 目的是避免将基准代码与主要工件打包在一起。 3.1添加BenchmarkBase文件在2上方指示。 该文件将用作基准测试的入口点并包含测试的所有全局配置。 我编写的类正在寻找一个包含配置属性的“ benchmark.properties”文件上面在3中指示。 JMH可以选择输出文件结果并且此配置是为JSON设置的。 结果与您的持续集成工具一起使用可以应该存储以供历史使用。 此代码段是Maven运行的Benchmark流程的基本工具和入口点在下面的步骤5中进行设置。此时项目应该能够运行基准测试因此让我们添加一个测试用例。 SpringBootApplication
public class BenchmarkBase {public static void main(String[] args) throws RunnerException, IOException {Properties properties PropertiesLoaderUtils.loadAllProperties(benchmark.properties);int warmup Integer.parseInt(properties.getProperty(benchmark.warmup.iterations, 5));int iterations Integer.parseInt(properties.getProperty(benchmark.test.iterations, 5));int forks Integer.parseInt(properties.getProperty(benchmark.test.forks, 1));int threads Integer.parseInt(properties.getProperty(benchmark.test.threads, 1));String testClassRegExPattern properties.getProperty(benchmark.global.testclassregexpattern, .*Benchmark.*);String resultFilePrefix properties.getProperty(benchmark.global.resultfileprefix, jmh-);ResultFormatType resultsFileOutputType ResultFormatType.JSON;Options opt new OptionsBuilder().include(testClassRegExPattern).warmupIterations(warmup).measurementIterations(iterations).forks(forks).threads(threads).shouldDoGC(true).shouldFailOnError(true).resultFormat(resultsFileOutputType).result(buildResultsFileName(resultFilePrefix, resultsFileOutputType)).shouldFailOnError(true).jvmArgs(-server).build();new Runner(opt).run();}private static String buildResultsFileName(String resultFilePrefix, ResultFormatType resultType) {LocalDateTime date LocalDateTime.now();DateTimeFormatter formatter DateTimeFormatter.ofPattern(mm-dd-yyyy-hh-mm-ss);String suffix;switch (resultType) {case CSV:suffix .csv;break;case SCSV:// Semi-colon separated valuessuffix .scsv;break;case LATEX:suffix .tex;break;case JSON:default:suffix .json;break;}return String.format(target/%s%s%s, resultFilePrefix, date.format(formatter), suffix);}} 4创建一个类来对操作进行基准测试。 请记住基准测试将针对整个方法主体进行包括日志记录文件读取外部资源等。请注意要进行基准测试并减少或删除依赖项以便隔离主题代码以确保对结果的信心更高。 在此示例中在 State(Scope.Benchmark)
BenchmarkMode(Mode.AverageTime)
OutputTimeUnit(TimeUnit.MICROSECONDS)
public class SerializationBenchmark {private RecipeService service;private Recipe recipe;private byte[] protoRecipe;private String recipeAsJSON;Setup(Level.Trial)public void setup() {IngredientUsed jalepenoUsed new IngredientUsed(new Ingredient(Jalepeno, Spicy Pepper), MeasurementType.ITEM, 1);IngredientUsed cheeseUsed new IngredientUsed(new Ingredient(Cheese, Creamy Cheese), MeasurementType.OUNCE, 4);recipe RecipeTestUtil.createRecipe(My Recipe, Some spicy recipe using a few items, ImmutableList.of(jalepenoUsed, cheeseUsed));service new RecipeService(new ObjectMapper());protoRecipe service.recipeAsProto(recipe).toByteArray();recipeAsJSON service.recipeAsJSON(recipe);}Benchmarkpublic Messages.Recipe serialize_recipe_object_to_protobuf() {return service.recipeAsProto(recipe);}Benchmarkpublic String serialize_recipe_object_to_JSON() {return service.recipeAsJSON(recipe);}Benchmarkpublic Recipe deserialize_protobuf_to_recipe_object() {return service.getRecipe(protoRecipe);}Benchmarkpublic Recipe deserialize_json_to_recipe_object() {return service.getRecipe(recipeAsJSON);}} 标题该要点是从Protobuf序列化中提取的示例基准测试用例 现在当您执行测试jar时所有* Benchmark..java测试类都将运行但这通常并不理想因为该过程没有隔离并且对基准测试的时间和方式进行一些控制对于保持构建时间很重要下。 让我们构建一个Maven配置文件来控制何时运行基准测试并可能启动应用程序。 注意为了显示Maven集成测试启动/停止服务器的目的我已将其包含在博客文章中。 我会警告需要启动或停止应用程序服务器因为这可能会带来资源获取REST调用的成本而这并不是很孤立。 5概念是创建一个Maven配置文件以独立运行所有基准测试即没有单元测试或功能测试。 这将使基准测试可以与其余构建管道并行运行。 请注意该代码使用“ exec”插件并运行uber jar以查找到主类的完整类路径路径。 此外可执行文件范围仅限于“测试”源以避免将基准代码放入最终工件中。 profileidbenchmark/idpropertiesmaven.test.ITeststrue/maven.test.ITests/propertiesbuildplugins!-- Start application for benchmarks to test against --plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdexecutionsexecutionidpre-integration-test/idgoalsgoalstart/goal/goals/executionexecutionidpost-integration-test/idgoalsgoalstop/goal/goals/execution/executions/plugin!-- Turn off unit tests --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-surefire-plugin/artifactIdconfigurationexcludesexclude**/*Tests.java/excludeexclude**/*Test.java/exclude/excludes/configuration/pluginplugingroupIdorg.codehaus.mojo/groupIdartifactIdexec-maven-plugin/artifactIdversion1.5.0/versionexecutionsexecutiongoalsgoalexec/goal/goalsphaseintegration-test/phase/execution/executionsconfigurationexecutablejava/executableclasspathScopetest/classpathScopeargumentsargument-classpath/argumentclasspath /argumentcom.dev9.benchmark.BenchmarkBase/argumentargument.*/argument/arguments/configuration/plugin/plugins/build
/profile 此代码段显示了一个仅运行基准测试的maven配置文件示例。 6最后可选项目是在“持续集成”构建管道中创建一个可运行的构建步骤。 为了独立运行基准测试您或您的CI可以运行 mvn clean verify -Pbenchmark结论 如果您使用的是基于Java的项目则相对容易地将JMH添加到您的项目和管道中。 与项目关键区域相关的历史分类帐的好处对于保持较高的质量水平非常有用。 将JMH添加到您的管道还遵循持续交付原则包括反馈循环自动化可重复和不断改进。 考虑将JMH线束和一些测试添加到解决方案的关键区域。 翻译自: https://www.javacodegeeks.com/2016/12/adding-microbenchmarking-build-process.html微基准测试 r