std :: function lambda优化

时间:2016-02-11 16:59:19

标签: c++ memory-management lambda c++14 std-function

众所周知,

std::function存在性能问题,因为它可能会进行堆分配。承认,如果你100%诚实,在大多数情况下,一个堆分配应该不成问题......但是我们只是假设在特定情况下进行堆分配是不可取的或禁止的。也许我们正在进行几百万次回调,并且不希望为此进行几百万次堆分配。

所以......我们想避免堆分配。

Dr. Dobbs的文章Efficient Use of Lambda Expressions and std::function通过利用标准推荐并在每个主流标准库中实施的小对象优化,提出了优化std::function使用的建议。

本文详细解释了标准库如何复制仿函数,因为std::function对象可能比原始仿函数更长(尽管如果你确定它没有,你可以使用std::ref),这将是糟糕的魔力。此外,需要复制捕获,问题是:关闭的确切类型(或其大小)事先是未知的,因为它可能是具有任意数量捕获的任何类型的闭包,因此必须做出一些妥协。在一定大小的情况下,捕获将保存在function对象内的存储中,除此之外,它将被动态分配。存储很小,从12到16字节,所以假设64位构建,最多两个指针(不包括实际的函数指针)。

博士。因此,Dobbs建议(以及其他几个站点接受该建议,似乎没有太多反对意见)捕获对结构的引用,该结构包含对您实际想要捕获的内容的引用。这样,你只捕获一个引用,这是完美的,因为它总是适合小对象存储。

这是如何工作的?首先需要复制内容的假设是function对象可能比原始闭包的范围更长。当然,这意味着它比它拥有引用的结构更长,以及从该结构内部引用的任何内容。

这应该如何运作?既然我看不出它是如何起作用的,那么有一个更好的知名配方来解决这个问题吗? (不引用无效对象的那个)

1 个答案:

答案 0 :(得分:1)

如果函数对象的活动时间超过其调用函数(并且您正在捕获对堆栈中对象的引用),我认为它不应该工作。

在许多实际情况中,函数对象在本地使用,并且不会超过其调用者,然后您可以避免堆分配(但是再次,编译器可能能够优化引用和整个<head> </head> <body> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <div id='calendar'></div> </div> <script src='libs/fullcalender/lib/jquery.min.js'></script> <script src="libs/bootstrap/js/bootstrap.js"></script> <script src='libs/fullcalender/lib/moment.min.js'></script> <script src='libs/fullcalender/fullcalendar.js'></script> <script src="libs/fullcalender/lang/fi.js"></script> <script src="js/funktiot.js"></script> <script type='text/javascript'> luoKalenteri("#calendar", <?php echo $_GET["id"]; ?>); </script> </body> 技术可能没有必要)。

这是一个简单的test编译但崩溃(在C ++ 14模式下对clang进行测试。)