<div dir="ltr"><div style>Brian,</div><div style><br></div><div style>Attached are the output of two Rprof runs:</div><div style> - rp_profile_new.txt uses modify.args to match the arguments for set.portfolio.moments in constrained_objectve</div>
<div style> - rp_profile_old.txt is the existing code to match the arguments</div><div><br></div><div style>There is a slight performance improvement, but nothing significant. I used a simple objective to minimize mES using optimize_method="random" with search_size=1000. The dataset is all 13 indices from data(edhec).</div>
<div><br></div><div style>If you look at rp_profile_old, the total.time for set.portfolio.moments is 194.94 and total.pct is 98.82. This seems odd to me since set.portfolio.moments checks if the moments for mu, sigma, m3, and m4 are null. (e.g. if(is.null(momentargs$m3)) momentargs$m3 = PerformanceAnalytics:::<a href="http://M3.MM">M3.MM</a>(R))</div>
<div style><br></div><div style>It is as if all the moments are being calculated at each iteration in set.portfolio.moments, which shouldn't be happening. They should be passed from optimize.portfolio when they are set with momentFUN. I'll be able to look into this in more detail later this evening.</div>
<div style><br></div><div style>One thing I plan on trying is adding a formal "moments" argument to constrained_objective so that we can pass the object directly from optimize.portfolio. </div><div style><br></div>
<div style>Realistically, the moments *should* only need to be calculated once in optimize.portfolio and should not be recalculated in constrained_objective, correct?</div><div style><br></div><div style>Ross</div><div style>
 </div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 13, 2013 at 9:04 AM, Brian G. Peterson <span dir="ltr"><<a href="mailto:brian@braverock.com" target="_blank">brian@braverock.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">See responses inline.<div class="im"><br>
<br>
On 11/13/2013 10:06 AM, Ross Bennett wrote:<br>
<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
On Tue, Nov 12, 2013 at 9:49 PM, Brian G. Peterson <<a href="mailto:brian@braverock.com" target="_blank">brian@braverock.com</a><br></div><div class="im">
<mailto:<a href="mailto:brian@braverock.com" target="_blank">brian@braverock.com</a>>> wrote:<br>
<br>
    Ross, this is a very interesting prototype.<br>
<br>
    We haven't shied away from adding C dependencies in<br>
    PerformanceAnalytics or blotter or quantstrat.  All of them have<br>
    recently acquired compiled code.<br>
<br>
    The first part of your benchmark is a fair one, generating the<br>
    random portfolios, and one that I would expect compiled code to do<br>
    better than native R code (though we haven't spent any time<br>
    profiling or trying to improve the native R code either) because it<br>
    is a big loop.<br>
<br>
<br>
I'll look to see if there is a way to improve the R code here. At first<br>
glance it isn't obvious where performance could be improved, because it<br>
just a while loop as you stated. Perhaps something with how the<br>
weight_seq subsetting is done. Although the overall impact on random<br>
portfolios would be small because this is only called once, any<br>
improvements here could be used in rp_transform which is called by the<br>
mapping function passed to DEoptim. If I understand correctly, this is<br>
called tens of thousands of time so any incremental improvement could be<br>
a large net gain overall for optimize_method="DEoptim".<br>
</div></blockquote>
<br>
Yes, rewriting the mapping function in a compiled language may indeed help a lot.  I'm still not clear on *how much* is will help.  We probably need an Rprof run to figure it out.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    The second part of your benchmark is rather unfair though, as you<br>
    say yourself:<br>
<br>
    "Benchmark the optimization functions of PortfolioAnalytics and RcppRP.<br>
    The rp_optimize_v2 uses slimmed down C++ implementations of<br>
    constrained_objective and optimize.portfolio from<br>
    PortfolioAnalytics. The objective, constrained objective, and<br>
    optimization functions<br>
    must all be in C++ so that I can ”stay in C++ world” for the<br>
    optimization when calling constrained_objective for each set of<br>
    weights."<br>
<br>
    The entire point of constrained_objective is that the objective from<br>
    the portfolio specification is of arbitrary complexity, and will<br>
    typically include much more complex functions than 'mean' and 'sd'.<br>
<br>
<br>
I, perhaps naively, assumed that the most common objective functions<br>
used were mean, StdDev, and ES. What is your take on the most common<br>
complex objective functions? Perhaps these could be optimized or<br>
implemented in a compiled language. Depending on the function,<br>
improvements here would also likely be an overall net gain because they<br>
are called thousands or tens of thousands of times from<br>
constrained_objective.<br>
</blockquote>
<br></div>
Well, remember that there are lots of modifications even to portfolio covariances and ETL.  the Cornish Fisher stuff, modifications based on better estimates of the moments, etc.  Drawdowns and factor exposures are probably the others that are most often used in practice.<br>

<br>
Josh has some C code for doing the higher co-moment matrices that I want to get into PerformanceAnalytics sometime soon.  That code is very expensive in R.<div class="im"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
    So, keeping everything in C++ world isn't really possible with<br>
    arbitrary objectives, by construction, because the objectives can be<br>
    *any R function*.<br>
<br>
<br>
    That said, where would generally useful improvements (in handling<br>
    arbitrary objectives) likely lie?<br>
<br>
    * handling the loop over all the random weight vectors in compiled code:<br>
<br>
    This isn't likely to be a huge performance improvement with<br>
    arbitrary objectives, as the time spent in the loop is likely<br>
    dwarfed by the objective function itself.<br>
<br>
<br>
Agreed, I believe most of the time is spent in constrained_objective.<br>
</blockquote>
<br></div>
Again, it would be good to look at an Rprof run of both a simple portfolio spec and a complex one.  Recent examples of more nuanced ones can be found in Peter's symposium2013 code in the sandbox.<div class="im"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    * improved handling of arguments and argument matching<br>
<br>
    This one could be huge, but also doesn't require compiled code.<br>
      Josh Ulrich recently came up with huge speed improvements in<br>
    quantstrat  in part by improving the argument matching and calling<br>
    of arbitrary functions.  The prototype of that code in quantstrat<br>
    came from PortfolioAnalytics.  The key improvement was in not<br>
    evaluating large arguments. In this case, that would be the returns<br>
    time series and the moments and co-moments.  This trick could and<br>
    probably should be ported to PortfolioAnalytics.<br>
<br>
<br>
I saw his post on FOSS trading and was very impressed by the performance<br>
gain. I would really like to look into this for PortfolioAnalytics. I<br>
started looking the quantstrat source code, but wasn't exactly sure what<br>
I was looking for. Can you point me to the diff or function (or a simple<br>
example) where this was done?<br>
</blockquote>
<br></div>
The function is modify.args in utils.R, and you can see it used in a manner very similarly to how we use it in PortA in fn ApplyIndicators in indicators.R<div class="im"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    We saw Dirk try to create a faster C++ version of DEoptim a few<br>
    years ago.  His RcppDEoptim didn't pass dots (...) to the objective<br>
    function.  Oops.  The entire performance gain came from this lack of<br>
    ability to use an arbitrary objective.  When dots were added back<br>
    in, the C++ version of DE is slower than the C version (as you'd<br>
    expect). Passing dots to the objective isn't exactly optional<br>
    outside of toy examples.<br>
<br>
    * general improvements in optimize.portfolio<br>
<br>
    Not clear without profiling, but i wouldn't expect this to be more<br>
    than a fraction of the runtime with real objectives.<br>
<br>
    * general improvements in constrained_objective<br>
<br>
    There is almost certainly a role for compiled code in<br>
    constrained_objective.  This is a very large, complex function that<br>
    could definitely be improved.  The core functionality of calling<br>
    arbitrary objectives as specified by the user can't be given up.<br>
    though, or we lose the reason to allow an arbitrary portfolio<br>
    specification in the first place.  Obviously, both C and C++ can<br>
    call back to R code from compiled code.  We do this already in<br>
    DEoptim to call the objective (constrained_objective in PortA) from<br>
    DEoptim's C code.<br>
<br>
<br>
My first step will be to optimize constrained_objective in R code.<br>
Assuming we take the step to write constrained_objective in compiled<br>
code, how much of an overhead or performance hit is there with<br>
repeatedly calling back to R from C or C++?<br>
</blockquote>
<br></div>
Like any other function execution overhead.  If you can avoid evaluating the arguments, it's very low cost.  As I said, DEoptim does this from C to call the objective function.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    Are optimize.portfolio and constrained_objective complex enough that<br>
    a dependency on Rcpp would be worth it?  Quite possibly.  C code<br>
    makes a lot of sense when the code can be kept compact and the<br>
    overhead of defining objects in C isn't too great.  C++ or Rcpp<br>
    makes sense when the complexity of the functions increases and the<br>
    code would be more legible and maintainable in C++ than C.  Is<br>
    constrained_objective complex enough to benefit from C++.  Maybe.<br>
<br>
    I think we'd need to be fair and ask where the performance gains<br>
    come from and how we could gain a generic, generally useful<br>
    improvement in PortfolioAnalytics.<br>
<br>
    If it makes sense, improving optimize.portfolio and<br>
    constrained_objective would improve the performance of<br>
    PortfolioAnalytics for all solvers, not just random portfolios.<br>
      That gain would need to come from benefits realizable even with an<br>
    arbitrarily complex portfolio specification.<br>
<br>
<br>
Thanks for the detailed breakdown and analysis of improving the<br>
performance in PortfolioAnalytics!<br>
</blockquote>
<br></div>
Absolutely.  Thanks for working on it!<br>
<br>
<br>
Regards,<br>
<br>
 Brian<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<br>
    On 11/12/2013 10:43 PM, Ross Bennett wrote:<br>
<br>
        All,<br>
<br>
        Over the course of the google summer of code project, I learned<br>
        a lot<br>
        about the random portfolios algorithm (among many other topics) and<br>
        became quite fascinated with the concept. I had some free time<br>
        over the<br>
        weekend and decided to implement random portfolio optimization using<br>
        Rcpp. My motivation for doing this was to learn C++ and Rcpp with no<br>
        expectation of how much faster this could actually be.<br>
<br>
        Here are the results of two benchmarks I did.<br>
<br>
        This first benchmark is just generating random portfolios.<br>
<br>
              test replications elapsed relative<br>
        1     pa             10 188.74     6.583<br>
        2 rcpp_s           10   28.67    1.000<br>
<br>
        The next benchmark is the actual optimization.<br>
<br>
            test replications elapsed relative<br>
        1   pa            10  211.027    808.5<br>
        2 rcpp           10      0.261    1.000<br>
<br>
        I am a beginner at C++ so I am pretty sure there are further<br>
        improvements that can be made with my C++ code.<br>
<br>
        The benchmark results got me thinking that we might be able to<br>
        use this<br>
        in PortfolioAnalytics. The RcppRP package I started this weekend is<br>
        really rough around the edges, but with some more improvements could<br>
        serve as an alternate optimization method for random portfolios. We<br>
        could have something like optimize.portfolio(...,<br>
        optimize_method="random_rcpp") that calls the proper functions<br>
        from RcppRP.<br>
<br>
        The RcppRP package is on my github page if you are interested in<br>
        looking<br>
        at the code.<br></div></div>
        <a href="https://github.com/rossb34/__RcppRP" target="_blank">https://github.com/rossb34/__<u></u>RcppRP</a><div class="im"><br>
        <<a href="https://github.com/rossb34/RcppRP" target="_blank">https://github.com/rossb34/<u></u>RcppRP</a>><br>
<br>
        Any thoughts on if this is worth continuing to pursue? Either<br>
        way I plan<br>
        to continue working on RcppRP for the sole purpose of learning<br>
        C++ and Rcpp.<br>
<br>
        Regards,<br>
        Ross<br>
<br>
<br>
<br></div>
        ______________________________<u></u>___________________<br>
        GSoC-PortA mailing list<br>
        <a href="mailto:GSoC-PortA@lists.r-forge.r-__project.org" target="_blank">GSoC-PortA@lists.r-forge.r-__<u></u>project.org</a><br>
        <mailto:<a href="mailto:GSoC-PortA@lists.r-forge.r-project.org" target="_blank">GSoC-PortA@lists.r-<u></u>forge.r-project.org</a>><br>
        <a href="http://lists.r-forge.r-__project.org/cgi-bin/mailman/__listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-__<u></u>project.org/cgi-bin/mailman/__<u></u>listinfo/gsoc-porta</a><div class="im"><br>

        <<a href="http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-<u></u>project.org/cgi-bin/mailman/<u></u>listinfo/gsoc-porta</a>><br>
<br>
<br>
<br>
    --<br>
    Brian G. Peterson<br>
    <a href="http://braverock.com/brian/" target="_blank">http://braverock.com/brian/</a><br></div>
    Ph: <a href="tel:773-459-4973" value="+17734594973" target="_blank">773-459-4973</a> <tel:<a href="tel:773-459-4973" value="+17734594973" target="_blank">773-459-4973</a>><br>
    IM: bgpbraverock<br>
    ______________________________<u></u>___________________<br>
    GSoC-PortA mailing list<br>
    <a href="mailto:GSoC-PortA@lists.r-forge.r-__project.org" target="_blank">GSoC-PortA@lists.r-forge.r-__<u></u>project.org</a><br>
    <mailto:<a href="mailto:GSoC-PortA@lists.r-forge.r-project.org" target="_blank">GSoC-PortA@lists.r-<u></u>forge.r-project.org</a>><br>
    <a href="http://lists.r-forge.r-__project.org/cgi-bin/mailman/__listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-__<u></u>project.org/cgi-bin/mailman/__<u></u>listinfo/gsoc-porta</a><br>
    <<a href="http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-<u></u>project.org/cgi-bin/mailman/<u></u>listinfo/gsoc-porta</a>><div class="im"><br>
<br>
<br>
<br>
<br>
______________________________<u></u>_________________<br>
GSoC-PortA mailing list<br>
<a href="mailto:GSoC-PortA@lists.r-forge.r-project.org" target="_blank">GSoC-PortA@lists.r-forge.r-<u></u>project.org</a><br>
<a href="http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-<u></u>project.org/cgi-bin/mailman/<u></u>listinfo/gsoc-porta</a><br>
<br>
</div></blockquote><div class="HOEnZb"><div class="h5">
<br>
<br>
-- <br>
Brian G. Peterson<br>
<a href="http://braverock.com/brian/" target="_blank">http://braverock.com/brian/</a><br>
Ph: <a href="tel:773-459-4973" value="+17734594973" target="_blank">773-459-4973</a><br>
IM: bgpbraverock<br>
______________________________<u></u>_________________<br>
GSoC-PortA mailing list<br>
<a href="mailto:GSoC-PortA@lists.r-forge.r-project.org" target="_blank">GSoC-PortA@lists.r-forge.r-<u></u>project.org</a><br>
<a href="http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta" target="_blank">http://lists.r-forge.r-<u></u>project.org/cgi-bin/mailman/<u></u>listinfo/gsoc-porta</a><br>
</div></div></blockquote></div><br></div>