{"id":5910,"date":"2015-03-27T09:00:09","date_gmt":"2015-03-27T13:00:09","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/?p=5910"},"modified":"2015-03-27T05:21:45","modified_gmt":"2015-03-27T09:21:45","slug":"cache-your-nuts-to-eat-later","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2015\/03\/27\/cache-your-nuts-to-eat-later\/","title":{"rendered":"Cache Your Nuts to Eat Later"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/32620\">Greg's<\/a> pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/49949-cachedcall\">cachedcall<\/a> by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/870202-aslak-grinsted\">Aslak Grinsted<\/a>.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Call That Expensive Computation Once!<\/a><\/li>\r\n         <li><a href=\"#2\">What Is Caching?<\/a><\/li>\r\n         <li><a href=\"#3\">How Is It Done?<\/a><\/li>\r\n         <li><a href=\"#4\">Doesn't MATLAB Cache Functions Already?<\/a><\/li>\r\n         <li><a href=\"#5\">Should Every Function Call Be Cached?<\/a><\/li>\r\n         <li><a href=\"#7\">Why Did I Choose This Entry?<\/a><\/li>\r\n         <li><a href=\"#8\">Could You Use Function Caching?<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Call That Expensive Computation Once!<a name=\"1\"><\/a><\/h3>\r\n   <p>Aslak has created an ingenious utility that stores the results to a function call, so that if the same function is called\r\n      again with the same inputs, it will return the stored results instead of recomputing the answer.\r\n   <\/p><pre style=\"font-style:oblique\">               StandardCall    FirstCacheCall    SecondCacheCall    SpeedUp\r\n               ____________    ______________    _______________    _______\r\n\r\n    isprime       2.4633         2.4228          0.0036991           99.85 \r\n    urlread    0.0048197        0.01007          0.0038378          20.372 \r\n    sim         0.029784       0.034612          0.0038576          87.048 \r\n\r\n<\/pre><h3>What Is Caching?<a name=\"2\"><\/a><\/h3>\r\n   <p>The <a href=\"http:\/\/en.wikipedia.org\/wiki\/Cache_%28computing%29\">definition<\/a> is to store a resource for future use.  In computing, it generally refers to storing data in memory in a fashion that it\r\n      can be rapidly accessed at a later time.\r\n   <\/p>\r\n   <p>In fact developing algorithms for implicitly creating caches is always one of those areas under research in development.<\/p>\r\n   <p>However, in this particular example, the creation of the cache is explicit.<\/p>\r\n   <h3>How Is It Done?<a name=\"3\"><\/a><\/h3>\r\n   <p>The simplified version is, for unique instance of a function call, the results of that function call are stored in a file.\r\n       A data table is developed to link the unique function calls to specific data files.  When a function call is applied, CACHECALL\r\n      determines if that particular function call situation has been performed before. If so, return the stored results, otherwise\r\n      call the desired function and store the results for later use.\r\n   <\/p>\r\n   <p>For me, the part I find most fascinating is Aslak is able to develop unique identifiers for each function call situation based\r\n      on the function, inputs, classes, etc. He actually ends up leveraging another File Exchange entry <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/31272-datahash\">DataHash<\/a> by Jan Simon.\r\n   <\/p>\r\n   <p>The DataHash uses MATLAB's inherent ability to call Java code to develop his hash tables and unique identifiers.<\/p>\r\n   <h3>Doesn't MATLAB Cache Functions Already?<a name=\"4\"><\/a><\/h3>\r\n   <p>Yes, but generally not based on specific inputs. When a function is called the first time, if it hasn't been used yet in the\r\n      current MATLAB session, then that function must be loaded into memory. Subsequent calls to the same function require less\r\n      time because the function is already in memory, but it doesn't store the results of specific computations for future use.\r\n   <\/p>\r\n   <p>The same thing applies if the function has been edited. It must be reloaded into memory the first time it is called.<\/p>\r\n   <h3>Should Every Function Call Be Cached?<a name=\"5\"><\/a><\/h3>\r\n   <p>Probably not. There is a penalty for the caching process.  If the resulting cached results are never used, then that penalty\r\n      is wasted.  Also caching involves writing to disc, which causes the slowdown in the following results.\r\n   <\/p><pre style=\"font-style:oblique\">                     StandardCall    FirstCacheCall    SecondCacheCall    SpeedUp\r\n                     ____________    ______________    _______________    _______\r\n\r\n    rand                 1.0061         19.194            4.3404          -331.4 \r\n    triangulation    3.7253e-05      0.0066531         0.0051827          -13812 \r\n\r\n<\/pre><p>It probably only makes sense in cases where there are a limited number of input scenarios that will occur multiple times,\r\n      and takes longer than writing to disc.\r\n   <\/p>\r\n   <p>That's not always predictable, so it may require some <a href=\"\">profiling<\/a> to determine if it's worth the cost of caching.\r\n   <\/p>\r\n   <h3>Why Did I Choose This Entry?<a name=\"7\"><\/a><\/h3>\r\n   <p>This is a clever method to speed up repetitive computations when there are a relatively finite number of possible inputs.<\/p>\r\n   <p>I'm impressed that Aslak was able to figure out how to identify unique function calls.  When I saw this entry, it was one\r\n      of those \"I wish I had thought of that!\" moments.\r\n   <\/p>\r\n   <p>In addition, Aslak does a nice job of architecting the software and documenting his public interface to the caching features.<\/p>\r\n   <h3>Could You Use Function Caching?<a name=\"8\"><\/a><\/h3>\r\n   <p>Have you tried this out? What do you think about it? Should this type of caching be available in MATLAB?<\/p>\r\n   <p>You can leave your comments <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=5910#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_00eecde5bae14a9c86d9d096ffbd4815() {\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='00eecde5bae14a9c86d9d096ffbd4815 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 00eecde5bae14a9c86d9d096ffbd4815';\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        author = 'Greg Wolff';\r\n        copyright = 'Copyright 2015 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 author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\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      \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_00eecde5bae14a9c86d9d096ffbd4815()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 8.5<br><\/p>\r\n<\/div>\r\n<!--\r\n00eecde5bae14a9c86d9d096ffbd4815 ##### SOURCE BEGIN #####\r\n%% Cache Your Nuts to Eat Later\r\n% Function Result Caching in MATLAB\r\n%\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/32620 Greg's> pick this week is \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/49949-cachedcall cachedcall> by <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/870202-aslak-grinsted Aslak Grinsted>.\r\n% \r\n%% Call That Expensive Computation Once!\r\n% Aslak has created an ingenious utility that stores the results to a function call, so that if the same function is called again \r\n% with the same inputs, it will return the stored results instead of recomputing the answer.\r\n%\r\nrootFolder = fileparts(mfilename('fullpath'));\r\naddpath(fullfile(rootFolder, 'cachedcall'));\r\nresult = cachedcall(@compareCachedCalls); \r\nresult.SpeedUp = (result.StandardCall - result.SecondCacheCall).\/result.StandardCall* 100; \r\ndisp(result(1:3, :));\r\n \r\n %% What Is Caching?\r\n % The <https:\/\/en.wiktionary.org\/wiki\/cache definition> is to store a resource for future use.  In \r\n % computing, it generally refers to storing data in memory in a fashion that it can be rapidly accessed\r\n % at a later time.\r\n %\r\n % In fact developing algorithms for implicitly creating caches is always one of those areas under \r\n % research in development.\r\n %\r\n % However, in this particular example, the creation of the cache is explicit.\r\n \r\n %% How Is It Done?\r\n % The simplified version is, for unique instance of a function call, the results of that function call\r\n % are stored in a file.  A data table is developed to link the unique function calls to specific data \r\n % files.  When a function call is applied, CACHECALL determines if that particular function call \r\n % situation has been performed before. If so, return the stored results, otherwise call the desired\r\n % function and store the results for later use.\r\n %\r\n % For me, the part I find most fascinating is Aslak is able to develop unique identifiers for each\r\n % function call situation based on the function, inputs, classes, etc. He\r\n % actually ends up leveraging another File Exchange entry <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/31272-datahash\">DataHash<\/a> by Jan Simon.\r\n %\r\n % The DataHash uses MATLAB's inherent ability to call Java code to develop his hash tables and unique identifiers.\r\n \r\n  %% Doesn't MATLAB Cache Functions Already?\r\n % Yes, but generally not based on specific inputs. When a function is called the first time, if it \r\n % hasn't been used yet in the current MATLAB session, then that function must be loaded into memory.\r\n % Subsequent calls to the same function require less time because the function is already in memory,\r\n % but it doesn't store the results of specific computations for future use.\r\n % \r\n % The same thing applies if the function has been edited. It must be reloaded into memory the first time\r\n % it is called.\r\n \r\n %% Should Every Function Call Be Cached?\r\n % Probably not. There is a penalty for the caching process.  If the resulting cached results are never\r\n % used, then that penalty is wasted.  Also caching involves writing to disc, which causes the slowdown in the following results.\r\n \r\n disp(result(4:end, :));\r\n \r\n %%\r\n % It probably only makes sense in cases where there are a limited number\r\n % of input scenarios that will occur multiple times, and takes longer than writing to disc.  \r\n %\r\n % That's not always predictable, so it may require some\r\n % < profiling>\r\n % to determine if it's worth the cost of caching.\r\n \r\n %% Why Did I Choose This Entry?\r\n % This is a clever method to speed up repetitive computations when there are a relatively finite\r\n % number of possible inputs.\r\n %\r\n % I'm impressed that Aslak was able to figure out how to identify unique function calls.  When I saw \r\n % this entry, it was one of those \"I wish I had thought of that!\" moments.\r\n %\r\n % In addition, Aslak does a nice job of architecting the software and documenting his public interface to the caching features.\r\n \r\n %% Could You Use Function Caching?\r\n % Have you tried this out? What do you think about it? Should this type of caching be available in MATLAB?\r\n %\r\n % You can leave your comments <https:\/\/blogs.mathworks.com\/pick\/?p=5910#respond here>.\r\n \r\n \r\n\r\n \r\n \r\n\r\n\r\n\r\n##### SOURCE END ##### 00eecde5bae14a9c86d9d096ffbd4815\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      Greg's pick this week is cachedcall by Aslak Grinsted.\r\n      \r\n   \r\n   Contents\r\n   \r\n      \r\n         Call That... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2015\/03\/27\/cache-your-nuts-to-eat-later\/\">read more >><\/a><\/p>","protected":false},"author":36,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5910"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/36"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=5910"}],"version-history":[{"count":5,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5910\/revisions"}],"predecessor-version":[{"id":5922,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5910\/revisions\/5922"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=5910"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=5910"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=5910"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}