Chain-Load: investigate std::function inline-storage
...which is crucial for the solution pursued at the moment; std::function is known to apply a small-object optimisation, yet unfortunately there are no guarantees by the C++ standard (it is only mandated that std::function handles a bare function pointer without overhead) Other people have investigated that behaviour already, indicating that at least one additional »slot« of data can be handled with embedded storage in all known implementations (while libstdc++ seemingly imposes the strongest limitations) https://stackoverflow.com/a/77202545/444796 This experiment in the unit-test shows that for my setup (libstdc++ and GCC-8) only a lambda capturing a single pointer is handled entirely embedded into the std::function; already a lambda capturing a shared-ptr leads to overflow into heap
This commit is contained in:
parent
3c713a4739
commit
98078b9bb6
2 changed files with 103 additions and 6 deletions
|
|
@ -30,7 +30,9 @@
|
|||
#include "lib/lazy-init.hpp"
|
||||
//#include "lib/format-string.hpp"
|
||||
//#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/testdummy.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp" /////////////////////TODO TODOH
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <array>
|
||||
|
||||
|
|
@ -40,6 +42,7 @@ namespace lib {
|
|||
namespace test{
|
||||
|
||||
// using util::_Fmt;
|
||||
using util::isSameObject;
|
||||
using lib::meta::isFunMember;
|
||||
// using lib::meta::_FunRet;
|
||||
// using err::LUMIERA_ERROR_LIFECYCLE;
|
||||
|
|
@ -73,7 +76,7 @@ namespace test{
|
|||
simpleUse();
|
||||
|
||||
verify_trojanLambda();
|
||||
verify_inlineFunctorStorage();
|
||||
verify_inlineStorage();
|
||||
// verify_numerics();
|
||||
// verify_adaptMapping();
|
||||
// verify_dynamicChange();
|
||||
|
|
@ -161,8 +164,48 @@ namespace test{
|
|||
/** @test verify that std::function indeed stores a simple functor inline
|
||||
*/
|
||||
void
|
||||
verify_inlineFunctorStorage()
|
||||
verify_inlineStorage()
|
||||
{
|
||||
Dummy::checksum() = 0;
|
||||
using DummyManager = std::shared_ptr<Dummy>;
|
||||
|
||||
DummyManager dummy{new Dummy};
|
||||
long currSum = Dummy::checksum();
|
||||
CHECK (currSum > 0);
|
||||
CHECK (currSum == dummy->getVal());
|
||||
CHECK (1 == dummy.use_count());
|
||||
{
|
||||
// --- nested Scope ---
|
||||
auto lambda = [dummy]{ return &dummy; };
|
||||
CHECK (2 == dummy.use_count());
|
||||
CHECK (currSum == Dummy::checksum());
|
||||
|
||||
RawAddr location = lambda();
|
||||
CHECK (location == &lambda);
|
||||
|
||||
std::function funWrap{lambda};
|
||||
CHECK (funWrap);
|
||||
CHECK (not isSameObject (funWrap, lambda));
|
||||
CHECK (3 == dummy.use_count());
|
||||
CHECK (currSum == Dummy::checksum());
|
||||
|
||||
SHOW_EXPR(location)
|
||||
location = funWrap();
|
||||
SHOW_EXPR(location)
|
||||
SHOW_EXPR(RawAddr(&funWrap))
|
||||
SHOW_EXPR(RawAddr(dummy.get()))
|
||||
|
||||
std::function fuckWrap{[location]{ return &location; }};
|
||||
CHECK (fuckWrap);
|
||||
SHOW_EXPR(RawAddr(&location))
|
||||
SHOW_EXPR(RawAddr(fuckWrap()))
|
||||
SHOW_EXPR(RawAddr(&fuckWrap))
|
||||
}
|
||||
CHECK (1 == dummy.use_count());
|
||||
CHECK (currSum == Dummy::checksum());
|
||||
dummy.reset();
|
||||
CHECK (0 == dummy.use_count());
|
||||
CHECK (0 == Dummy::checksum());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -97285,8 +97285,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700786308827" ID="ID_627670298" MODIFIED="1700792001666" TEXT="der Trojanische-Funktor">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1700786329960" ID="ID_579721558" MODIFIED="1700786340287" TEXT="bettet einen shared_ptr ein">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#5b280f" CREATED="1700786329960" ID="ID_579721558" MODIFIED="1700795318817" TEXT="bettet einen shared_ptr ein">
|
||||
<linktarget COLOR="#e64156" DESTINATION="ID_579721558" ENDARROW="Default" ENDINCLINATION="556;-38;" ID="Arrow_ID_1803799256" SOURCE="ID_1318522029" STARTARROW="None" STARTINCLINATION="-60;-142;"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1700786341382" ID="ID_1622424867" MODIFIED="1700792030724" TEXT="delegiert über diesen um Funktor(Referenz) zu bekommen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -97297,12 +97298,65 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700786402490" ID="ID_846455233" MODIFIED="1700786418812" TEXT="Trick-Mechanismus zur this-Ermittlung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1700786427859" ID="ID_569731992" MODIFIED="1700786445020" TEXT="muß zu Beginn »proben«"/>
|
||||
<node CREATED="1700786446976" ID="ID_646471757" MODIFIED="1700786472569" TEXT="Zusatz-Problem: das λ sieht nur seine capture">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700786427859" ID="ID_569731992" MODIFIED="1700795340778" TEXT="muß zu Beginn »proben«">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700786446976" ID="ID_646471757" MODIFIED="1700795338010" TEXT="Zusatz-Problem: das λ sieht nur seine capture">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1700786476589" ID="ID_1376774629" MODIFIED="1700786490117" TEXT="⟶ also mehrstufig vorgehen"/>
|
||||
<node CREATED="1700786494226" ID="ID_990128277" MODIFIED="1700786508492" TEXT="generisch das Verhältnis zur std::function ermitteln"/>
|
||||
<node CREATED="1700786514967" ID="ID_1504854205" MODIFIED="1700786531452" TEXT="ebenso das Verhältnis von der std::function zu *this"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700794680114" ID="ID_1167943729" MODIFIED="1700795330803" TEXT="Vorraussetzung: Inline-Storage in std::function">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1700794692834" ID="ID_1004006687" MODIFIED="1700794700255" TEXT="Experiment (im Unit-Test)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1700794763222" ID="ID_122093052" MODIFIED="1700794788339" TEXT="bestätigt: λ-Addresse == Addresse des capture im Lambda">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e9ecac" COLOR="#ad0163" CREATED="1700794701860" ID="ID_1782883387" MODIFIED="1700794912605">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<u>Ergebnis</u>: funktioniert <b>nur</b> mit 1 »Slot«
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700794792578" ID="ID_1451884191" MODIFIED="1700794849741" TEXT="wenn Lambda einfachen ptr captured ⟼ Stack-Addresse"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700794830533" ID="ID_871196012" MODIFIED="1700794849742" TEXT="wenn Lambda shared_ptr captured ⟼ Heap-Addresse"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1700794933479" ID="ID_1065100472" MODIFIED="1700794949477" TEXT="⟹ Redesign">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700795056795" ID="ID_957544868" MODIFIED="1700795103642" TEXT="der Trojaner kann lediglich das Delegate aufrufen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700794955820" ID="ID_1318522029" MODIFIED="1700795323054" TEXT="Storage-Management muß separat erfolgen">
|
||||
<arrowlink COLOR="#e64156" DESTINATION="ID_579721558" ENDARROW="Default" ENDINCLINATION="556;-38;" ID="Arrow_ID_1803799256" STARTARROW="None" STARTINCLINATION="-60;-142;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700795105608" ID="ID_1474010761" MODIFIED="1700795128644" TEXT="bleibt nur der LazyInit-Mix-in selber">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1700795177255" ID="ID_1289910748" MODIFIED="1700795185358" TEXT="an beliebige Kopierbarkeit denken">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700795186661" ID="ID_1743434660" MODIFIED="1700795272779" TEXT="der schleppt dann wohl leider einen shared_ptr mit rum">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700795238903" ID="ID_762094742" MODIFIED="1700795272779" TEXT="man könnte höchstens nach Init abkoppeln">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700795252717" ID="ID_323775761" MODIFIED="1700795272780" TEXT="und den shared_ptr auch als Init-Flag mißbrauchen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue