开发人员区

高级软件开发与MATLAB

逗号分隔的善

大家好,今天我想介绍一下王长清。长清是MATLAB性能框架的首席开发人员,除了他提供的所有优秀性能测试功能外,他还发现了一种将性能结果集成到Jenkins中的非常简单的方法。过来看!

内容

Jenkins上的Matlab性能测试

“是建筑3301还是建筑3319?”CQ抓着头,满脸困惑。不知何故,他注意到了代码运行时的显著增加,但却不知道是哪一个变化引起的。他希望他已经记录了项目中每一个变更的执行情况。

随着持续集成成为敏捷过程中的关键原则之一,以及越来越多的产品采用持续交付实践,性能测试是添加到工作流中的关键步骤。s manbetx 845CQ从未想过引入性能回归,但当他意识到每次为了修复bug或新特性而接触代码时,都有这样的风险,但为时已晚。“一个通过的构建并不意味着一切都没问题”,CQ思考道,“我如何监控我的MATLAB项目在CI系统上的性能?”

这个问题的答案实际上有两个方面:

  1. 他需要为项目添加性能测试。
  2. 他需要为每个构建安排性能测试运行并报告结果。

如果您有一个MATLAB项目,并且想知道如何使用MATLAB中最新(也是最酷)的测试框架编写性能测试,这个页面是一个很好的起点。你也可以看看其他博客帖子我们在过去的主题上制作。在此博客中,我不会通过如何编写性能测试的详细信息,而是显示已经写入性能测试的示例项目。我正在使用的项目突出显示该示例是三种不同矩阵操作的超级轻量级​​“库”,计算给定矩阵的平均值,和和特征值。

matrix_mean.m

函数out=矩阵_平均值(M)% CQ的矩阵运算库和= matrix_sum (M);nrow = size(M, 1);ncol = size(M, 2);=金额/ (nrow * ncol);终止

matrix_sum.m..

函数OUT = matrix_sum(m)% CQ的矩阵运算库= 0;nrow =大小(M, 1);ncol =大小(M, 2);对于i=1:nrow对于j=1:ncol out=out+M(i,j);终止终止终止

matrix_eig.m.

函数out = matrix_eig(m)% CQ的矩阵运算库出=根(圆形(聚(m)));终止

tMatrix Library.m

Classdef.tMatrixLibrary < matlab.perftest.TestCase属性(testParameter)testmatrix = struct('中号',魔法(600),......'大尺寸',魔术(1000));终止方法(测试)函数testSum (testCase TestMatrix) matrix_sum (TestMatrix);终止函数testMean(testCase,TestMatrix)矩阵_-mean(TestMatrix);终止函数testeig(testcase,testmatrix)testcase.assertreturnstrue(@()大小(testmatrix,1)== size(testmatrix,2),......“Eig仅适用于方形矩阵”);testcase.startmeasuring;matrix_eig(testmatrix);testcase.stopmeasing;终止终止终止

性能测试tMatrix库对每个源文件都有三个参数化测试。注意,在testEig中,我们使用assertTrue保证测试中通过的矩阵为正方形的资格,以及开始/停止在测试点上指定测量边界。在MATLAB中运行性能测试有多种方法,但最简单的可能是使用Runperf.以获得结果。一旦我们有了结果,就可以很容易地使用Samplemumary.:

结果= runperf ('tmatrixlibrary.m')结果.Samplesummary.
正在运行tMatrix库。。。。。。完成tMatrix Library\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。6×7.7表表名,6×7 7表名,表名,表名,表名,表名,表名,表名,表表名,表表名,表示,平均,平均,平均,标准,平均,标准,平均,标准,平均,平均,标准,平均,标准,平均,平均,标准,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,平均,标准,平均,平均,平均,标准,标准,标准,标准Uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu17 0.0082113 0.00092846 0.0050781 0.0084503 0.0095599 t矩阵库/测试平均值(测试矩阵=中型)12 0.0021527 0.00020086 0.0019554 0.0021054 0.002559 t矩阵库/测试平均值(测试矩阵=大型)8 0.0085206 0.00062801 0.0077265 0.0084615 0.0093073 t矩阵库/测试平均值(测试矩阵=中型)4 0.15444 0.0010901 0.15364 0.15405 0.15604 t矩阵库/测试(TestMatrix=largeSize)4 0.41783 0.013677 0.40623 0.41421 0.43668

这些是较好的数字,可以从MATLAB命令窗口评估项目的性能。现在让我们看看我们如何在CI系统中报告它们。如果我们用Jenkins作为示例,我们可以创建包含上面显示的源和测试文件的“简单矩阵库”项目:

作为先决条件,要启用Jenkins上的性能数据的日志,可以使用性能插件关于詹金斯。该插件可以从Jenkins网站上搜索和安装插件管理器.它使得一个后构建过程能够从主要测试工具中捕获报告,然后在构建历史记录上生成趋势图。此外,它还允许根据报告的错误百分比将最新的构建状态设置为传递,不稳定或失败。有几种支持的报告格式包括万博1manbetx最终统计数据XML、JMeter格式、JUnitXML等。然而,我们为我们的MATLAB项目选择JMeter CSV格式,因为runperf的输出测量结果对象已经以表格形式存储了信息,正如您将看到的,从这些表中生成JMeter CSV非常简单。以下是详细的步骤:

步骤1:将性能结果转换为CSV格式

首先,我们将从一个测量结果对象创建一个JMeter CSV文件。首先,我们需要收集所需的信息。标准的JMeter CSV格式包括16个变量:时间戳,运行,标签,响应代码,响应消息,threadname.,数据库类型,成功,failureMessage,字节,千字节,grpThreads,allThreads,延迟,空闲时间,连接.有些变量对我们的用例很重要,有些可以忽略。有四种测试活性测量结果的表:timeStamp, elapsed(来自“MeasuredTime”),label(来自“Name”)和success(来自“Passed”)。因此,让我们使用上面runperf调用的结果。我们可以将这些列提取到一个samplesTable中,并重命名变量:

activityTable=vertcat(结果.测试活动);activityTable.Properties.VariableNames'
ans=12×1单元数组{'Name'}{'Passed'}{'Failed'}{'completed'}{'MeasuredTime'}{'Objective'}{'Timestamp'}{'Host'}{'Platform'}{'Version'}{'TestResult'}{'RunIdentifier'}
samplestable = chatmenttTable(ActivityTable.Objective ==分类({'样本'}),:);nrows = size(samplestable,1);%修剪表格并更改变量名称以符合JMeter CSV格式samplesTable = samplesTable(:, {)'时间戳',“测量时间”,“姓名”,“通过”});samplestable.properties.variablenames = {'时间戳',“过去的”,'标签',“成功”};

需要注意的几点事项是,JMeter中的时间戳处于UNIX样式格式,并且JMeter中报告的经过时间以毫秒为单位,两者都与MATLAB测量结果不同。此外,对于失败的情况,我们需要在jmeter中通过一些可接受的值替换测量结果中的缺失值NaN和NAT。让我们解决这两个清理项目:

%将时间戳转换为unix格式,并用以前的可用时间填充NaTsamplesTable。时间戳= fillmissing(samplesTable.timeStamp,'以前的'); samplesTable.timeStamp=posixtime(samplesTable.timeStamp)*1000;%将MeasuredTime转换为毫秒,并用0填充NaNsamplestable.elapsed = fillmissing(samplestable.elaped,'持续的', 0);samplesTable。运行= floor(samplesTable.elapsed*1000);

默认情况下,“Passed”列存储逻辑值,我们需要将它们转换为JMeter CSV的字符串:

将pass/fail逻辑转换为字符串samplestable.success = string(samplestable.success);

接下来,我们需要为12个对我们不太重要的其他变量创建一些默认值,并将它们附加到Samplestable:

%以JMeter CSV格式生成所需的其他列Repleatecode =零(nrows,1);resplyemessage = strings(nrows,1);threadname = strings(nrows,1);数据类型= strings(nrows,1);exturemessage = strings(nrows,1);bytes =零(nrows,1);staybytes =零(nrows,1);GRPTHREADS = ONE(NROWS,1);Allthreads = ON(NROWS,1);延迟=零(nrows,1); idleTime = zeros(nrows, 1); connect = zeros(nrows, 1); auxTable = table(responseCode, responseMessage, threadName, dataType,......exturemessage,bytes,staybytes,grpthreads,harthreads,......延迟、空闲时间、连接);%将附加列附加到原始表JMeterTable = [samplesTable, auxTable];

瞧!现在我们有了一个JMeter格式的表格,其中包含完整的16个变量。我们现在可以简单地用可写函数将其写入CSV文件。请注意,字符串被引用以确保测试名称中的逗号不被视为分隔符。

%将完整表写入CSV文件writetable (JMeterTable“PerformanceTestResult.csv”,“QuoteStrings”, 真的);

步骤2:配置构建和构建后操作

现在我们可以在Jenkins上设置性能监控!好消息是,在第1步努力工作后,其余的是超级简单。只需将我们开发的转换代码放入函数中(我们打电话给它convertToJMeterCSV))并确保它可以从Jenkins Build的工作空间中获得。然后,您只需调用该函数作为Jenkins构建的一部分。打开项目配置页面,添加“执行Windows Batch命令”构建步骤并将以下命令写入命令​​:

matlab -nodisplay -wait -log -r "convertToJMeterCSV(runperf('tMatrixLibrary.m'));出口”

Runperf的输出将被转换并保存到本地“PerformancetestResult.csv”。

接下来,点击“添加一个后期构建操作”。在Jenkins上成功安装性能插件后,将出现“发布性能测试结果报告”选项。选择它,并在“Source data files”字段中输入csv文件名。也有其他的选择调整,但我们将保持他们的现状。单击保存按钮,退出配置界面。

步骤3:构建项目并回顾趋势

一切都完成了,您可以多次构建项目,然后单击左侧的“性能趋势”链接以查看响应时间和错误百分比的趋势图:

注意响应时间趋势中的统计数据在所有测试中都计算,这就是为什么中位值与平均值不同。我们可以通过点击任何构建来达到趋势的另一个趋势(在我们的情况下说#14),然后单击“性能趋势”链接:

在这里,我们将看到一个漂亮的汇总表,其中显示了所有测试的统计数据,绿色/红色的指示器显示了与上一个构建版本相比的结果差异。所有未通过的测试都会显示为红色,幸好我们没有这些测试。

这就是我们如何为Jenkins的Matlab项目添加绩效报告并不那么容易吗?分享您对如何改进过程的思考。是否有任何其他性能统计趋势您希望遵循您的MATLAB项目?




发布与MATLAB®R2018a

|

评论

要发表评论,请点击这里登录您的MathWorks帐户或创建新的。