{"id":640,"date":"2016-06-30T02:34:14","date_gmt":"2016-06-30T02:34:14","guid":{"rendered":"https:\/\/blogs.mathworks.com\/developer\/?p=640"},"modified":"2016-06-30T13:59:31","modified_gmt":"2016-06-30T13:59:31","slug":"performance-trends","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/developer\/2016\/06\/30\/performance-trends\/","title":{"rendered":"Trending Now!"},"content":{"rendered":"<div class=\"content\"><p>Today it is my pleasure to introduce my MathWorks colleague Anoush Najarian. Anoush is an engineering manager on the MATLAB performance team and she has been instrumental in many great projects such as the performance testing framework we have been blogging about as well as the significant performance improvements with the new MATLAB execution engine in R2015b. As it turns out she is also voraciously involved in the maker community and she can be seen doing all sorts of fun Internet of Things projects like <a href=\"https:\/\/twitter.com\/ThirstyParsley\">A Tweeting Plant<\/a>. That's good news for us because she can now use her performance know-how along with her familiarity with the ThingSpeak IoT platform to demonstrate how easy it is to use the platform to track the performance trends of your code over time. So without further ado let's hear from Anoush:<\/p><p>It's important to visualize results from our performance test runs!  Why?  People are awesome at spotting patterns, and learn better from pictures.<\/p><p>I love using <a href=\"https:\/\/thingspeak.com\">ThingSpeak<\/a> for maker projects.  For this post, I thought it would be fun and useful to get ThingSpeak to help track and analyze trends from <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/performance-testing-framework.html\">MATLAB Performance Testing Framework<\/a> runs. We're going to borrow an example Andy discussed in <a href=\"https:\/\/blogs.mathworks.com\/developer\/2016\/04\/11\/performance-ab-testing\/\">Peer Comparison<\/a>.<\/p><p>Let's figure out how to track the performance of Sarah's code over time.<\/p><p>First, let's run the Initial Code:<\/p><pre class=\"codeinput\">measResult = runperf(<span class=\"string\">'comparisonTest\/InitialCode'<\/span>);\r\nsamples = measResult.Samples\r\n<\/pre><pre class=\"codeoutput\">Running comparisonTest\r\n........\r\nDone comparisonTest\r\n__________\r\n\r\n\r\nsamples = \r\n\r\n               Name               MeasuredTime         Timestamp                    Host               Platform           Version                      RunIdentifier            \r\n    __________________________    ____________    ____________________    _________________________    ________    _____________________    ____________________________________\r\n\r\n    comparisonTest\/InitialCode    23.443          29-Jun-2016 16:44:18    Anoushs-MacBook-Pro.local    maci64      9.0.0.341360 (R2016a)    f0918bed-906d-4fed-93c5-dd9bb2241836\r\n    comparisonTest\/InitialCode    23.662          29-Jun-2016 16:44:41    Anoushs-MacBook-Pro.local    maci64      9.0.0.341360 (R2016a)    f0918bed-906d-4fed-93c5-dd9bb2241836\r\n    comparisonTest\/InitialCode    24.057          29-Jun-2016 16:45:05    Anoushs-MacBook-Pro.local    maci64      9.0.0.341360 (R2016a)    f0918bed-906d-4fed-93c5-dd9bb2241836\r\n    comparisonTest\/InitialCode    24.207          29-Jun-2016 16:45:30    Anoushs-MacBook-Pro.local    maci64      9.0.0.341360 (R2016a)    f0918bed-906d-4fed-93c5-dd9bb2241836\r\n\r\n<\/pre><p>We set up our ThingSpeak channel fields to mimic the data structure of the performance testing framework. (Take a look at <a href=\"https:\/\/www.mathworks.com\/help\/thingspeak\/getting-started-with-thingspeak.html\">Getting Started with ThingSpeak<\/a>!)  You can use our public channel to post your data, all the code in this post will work.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsSetup.png\" alt=\"\"> <\/p><p>In order to post our data to ThingSpeak, we need to format it a bit, and provide a Write Key for <a href=\"https:\/\/thingspeak.com\/channels\/82845\">our channel<\/a>:<\/p><pre class=\"codeinput\">dataTable = table(samples.Timestamp, cellstr(samples.Platform), cellstr(samples.Host), cellstr(samples.Version), cellstr(samples.Name), cellstr(samples.RunIdentifier), samples.MeasuredTime);\r\nchannelID = 82845;\r\nwriteKey = <span class=\"string\">'H952GH69VMDB4C2X'<\/span>;\r\nthingSpeakWrite(channelID, dataTable, <span class=\"string\">'WriteKey'<\/span>, writeKey);\r\n<\/pre><p>We can include this script in our continuous integration workflow, or run it manually whenever we make changes to our algorithm.  The data is uploaded to ThingSpeak, and persists there.  We can manipulate it then using a collection of cool MATLAB tools on ThingSpeak.<\/p><p>We gradually implemented all of Sarah's optimizations.  Here is what our trend looks like so far this year; we included a bonus trend for the past couple of months:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsChannel.png\" alt=\"\"> <\/p><p>Here's the code running on ThingSpeak, driving the first of our MATLAB Visualizations.  You also can run it in your MATLAB session, and get a plot locally!<\/p><pre class=\"codeinput\">readChannelID = 82845;\r\ndata = thingSpeakRead(readChannelID, <span class=\"string\">'Fields'<\/span>, [4, 6], <span class=\"string\">'NumPoints'<\/span>, 649, <span class=\"string\">'OutputFormat'<\/span>, <span class=\"string\">'table'<\/span>);\r\nthingSpeakPlot(data.Timestamps, cellfun(@str2num, data.MeasuredTime), <span class=\"string\">'XLabel'<\/span>, <span class=\"string\">'Date'<\/span>, <span class=\"string\">'YLabel'<\/span>, <span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Measured Time, seconds'<\/span>, <span class=\"string\">'Grid'<\/span>, <span class=\"string\">'on'<\/span>, <span class=\"string\">'Marker'<\/span>, <span class=\"string\">'o'<\/span>, <span class=\"string\">'LineStyle'<\/span>,<span class=\"string\">'-'<\/span>,<span class=\"string\">'LineWidth'<\/span>,2, <span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Title'<\/span>, <span class=\"string\">'MATLAB Performance Testing Framework Trend For 2016'<\/span>);\r\n<\/pre><p>If we hover over the data points in the trend plots, or zoom in, we will spot the key optimizations that helped the performance of Sarah's code. Initial Code measured at around 23.8s:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsInitialCode.png\" alt=\"\"> <\/p><p>On February 20, we switched to Code with Preallocation, speeding up to around 22.3s, or by 6%:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsPreallocation.png\" alt=\"\"> <\/p><p>On May 2, we implemented the optimization to Vectorize the Inner Two loops; this sped up the code 100+-fold, to 0.2s.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsVectorized.png\" alt=\"\"> <\/p><p>Finally, on June 9, we implemented Vectorize the Inner Three Loops, and the code sped up to 0.06s, or by 67%.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsVectorizedTimes3.png\" alt=\"\"> <\/p><p>In all, our trends capture pretty awesome 400+-fold performance improvement in the past few months!<\/p><p>What's next?  We can use MATLAB Analysis and Visualization tools on ThingSpeak for more advanced data analysis, like looking at error bars and normalizing performance across a suite of tests.  We can set up email alerts in response to changes in our performance trends.<\/p><p>Let us know in comments how you've been tracking performance over time, and what visualizations and alerts would be useful to you!<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_26ea79e155c1449ca6c4d34afd3c7b90() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='26ea79e155c1449ca6c4d34afd3c7b90 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 26ea79e155c1449ca6c4d34afd3c7b90';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2016 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_26ea79e155c1449ca6c4d34afd3c7b90()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2016a<br><\/p><\/div><!--\r\n26ea79e155c1449ca6c4d34afd3c7b90 ##### SOURCE BEGIN #####\r\n%% \r\n% It's important to visualize results from our performance test runs!  Why?  People are awesome at spotting patterns, and learn better from pictures.\r\n% \r\n% I love using <https:\/\/thingspeak.com ThingSpeak> for maker projects.  For this post, I thought it would be fun and useful to get ThingSpeak to help track and analyze trends from <https:\/\/www.mathworks.com\/help\/matlab\/performance-testing-framework.html MATLAB Performance Testing Framework> runs.  \r\n% We're going to borrow an example Andy discussed in <https:\/\/blogs.mathworks.com\/developer\/2016\/04\/11\/performance-ab-testing\/ Peer Comparison>.\r\n% \r\n% Let's figure out how to track the performance of Sarah's code over time.  \r\n%\r\n% First, let's run the Initial Code:\r\n\r\nmeasResult = runperf('comparisonTest\/InitialCode');\r\nsamples = measResult.Samples\r\n\r\n%%\r\n% We set up our ThingSpeak channel fields to mimic the data structure of the performance testing framework. (Take a look at <https:\/\/www.mathworks.com\/help\/thingspeak\/getting-started-with-thingspeak.html Getting Started with ThingSpeak>!)  You can use our public channel to post your data, all the code in this post will work.\r\n%\r\n% <<2016PerfTrendsSetup.png>>\r\n%\r\n% In order to post our data to ThingSpeak, we need to format it a bit, and provide a Write Key for <https:\/\/thingspeak.com\/channels\/82845 our channel>:\r\n\r\ndataTable = table(samples.Timestamp, cellstr(samples.Platform), cellstr(samples.Host), cellstr(samples.Version), cellstr(samples.Name), cellstr(samples.RunIdentifier), samples.MeasuredTime);\r\nchannelID = 82845;\r\nwriteKey = 'H952GH69VMDB4C2X';\r\nthingSpeakWrite(channelID, dataTable, 'WriteKey', writeKey);\r\n\r\n%%\r\n% We can include this script in our continuous integration workflow, or run it manually whenever we make changes to our algorithm.  The data is uploaded to ThingSpeak, and persists there.  We can manipulate it then using a collection of cool MATLAB tools on ThingSpeak.\r\n%\r\n% We gradually implemented all of Sarah's optimizations.  Here is what our trend looks like so far this year; we included a bonus trend for the past couple of months:\r\n%\r\n% <<2016PerfTrendsChannel.png>>\r\n%\r\n% Here's the code running on ThingSpeak, driving the first of our MATLAB Visualizations.  You also can run it in your MATLAB session, and get a plot locally!\r\n\r\nreadChannelID = 82845;\r\ndata = thingSpeakRead(readChannelID, 'Fields', [4, 6], 'NumPoints', 649, 'OutputFormat', 'table');\r\nthingSpeakPlot(data.Timestamps, cellfun(@str2num, data.MeasuredTime), 'XLabel', 'Date', 'YLabel', ...\r\n    'Measured Time, seconds', 'Grid', 'on', 'Marker', 'o', 'LineStyle','-','LineWidth',2, ...\r\n    'Title', 'MATLAB Performance Testing Framework Trend For 2016');\r\n\r\n%%\r\n% If we hover over the data points in the trend plots, or zoom in, we will spot the key optimizations that helped the performance of Sarah's code. Initial Code measured at around 23.8s:\r\n%\r\n% <<2016PerfTrendsInitialCode.png>>\r\n% \r\n% On February 20, we switched to Code with Preallocation, speeding up to around 22.3s, or by 6%:\r\n%\r\n% <<2016PerfTrendsPreallocation.png>>\r\n% \r\n%\r\n% On May 2, we implemented the optimization to Vectorize the Inner Two loops; this sped up the code 100+-fold, to 0.2s.\r\n%\r\n% <<2016PerfTrendsVectorized.png>>\r\n%\r\n%\r\n% Finally, on June 9, we implemented Vectorize the Inner Three Loops, and the code sped up to 0.06s, or by 67%.\r\n%\r\n% <<2016PerfTrendsVectorizedTimes3.png>>\r\n%\r\n\r\n%%\r\n% In all, our trends capture pretty awesome 400+-fold performance improvement in the past few months!\r\n% \r\n% What's next?  We can use MATLAB Analysis and Visualization tools on ThingSpeak for more advanced data analysis, like looking at error bars and normalizing performance across a suite of tests.  We can set up email alerts in response to changes in our performance trends.\r\n%\r\n% Let us know in comments how you've been tracking performance over time, and what visualizations and alerts would be useful to you!\r\n\r\n##### SOURCE END ##### 26ea79e155c1449ca6c4d34afd3c7b90\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/developer\/files\/2016PerfTrendsChannel.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Today it is my pleasure to introduce my MathWorks colleague Anoush Najarian. Anoush is an engineering manager on the MATLAB performance team and she has been instrumental in many great projects such... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/developer\/2016\/06\/30\/performance-trends\/\">read more >><\/a><\/p>","protected":false},"author":90,"featured_media":647,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,7],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/640"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/users\/90"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/comments?post=640"}],"version-history":[{"count":14,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/640\/revisions"}],"predecessor-version":[{"id":661,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/640\/revisions\/661"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media\/647"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media?parent=640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/categories?post=640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/tags?post=640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}