working with expressions: how to minimize runtime construction time





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.



struct SE {
SE(char id, char n) : id(id), n(n) {}

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

char id, n;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

LHS lhs;
SE rhs;
};


The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.



For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.



auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }


I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:



SE('a',1);                        // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'


A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.



Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.



Is it possible to obtain that more of the contruction part is produced at compile time?



#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;

// forward declaration
template <typename LHS> struct ME;

struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}

ME<SE> operator,(const SE& r);

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

char id, n;
mutable bool outer;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }

~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

LHS lhs;
SE rhs;
mutable bool outer;
};

ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }

void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}

int main() {
demo('a',1,'b',1,'c',1);
return 0;
}









share|improve this question




















  • 3





    For working code, codereview.stackexchange.com seems more appropriate.

    – Jarod42
    Dec 28 '18 at 10:39











  • "How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

    – YSC
    Dec 28 '18 at 10:41











  • And this is what you do. See Jarod's comment then ;)

    – YSC
    Dec 28 '18 at 10:43


















0















I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.



struct SE {
SE(char id, char n) : id(id), n(n) {}

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

char id, n;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

LHS lhs;
SE rhs;
};


The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.



For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.



auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }


I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:



SE('a',1);                        // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'


A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.



Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.



Is it possible to obtain that more of the contruction part is produced at compile time?



#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;

// forward declaration
template <typename LHS> struct ME;

struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}

ME<SE> operator,(const SE& r);

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

char id, n;
mutable bool outer;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }

~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

LHS lhs;
SE rhs;
mutable bool outer;
};

ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }

void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}

int main() {
demo('a',1,'b',1,'c',1);
return 0;
}









share|improve this question




















  • 3





    For working code, codereview.stackexchange.com seems more appropriate.

    – Jarod42
    Dec 28 '18 at 10:39











  • "How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

    – YSC
    Dec 28 '18 at 10:41











  • And this is what you do. See Jarod's comment then ;)

    – YSC
    Dec 28 '18 at 10:43














0












0








0








I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.



struct SE {
SE(char id, char n) : id(id), n(n) {}

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

char id, n;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

LHS lhs;
SE rhs;
};


The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.



For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.



auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }


I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:



SE('a',1);                        // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'


A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.



Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.



Is it possible to obtain that more of the contruction part is produced at compile time?



#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;

// forward declaration
template <typename LHS> struct ME;

struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}

ME<SE> operator,(const SE& r);

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

char id, n;
mutable bool outer;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }

~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

LHS lhs;
SE rhs;
mutable bool outer;
};

ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }

void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}

int main() {
demo('a',1,'b',1,'c',1);
return 0;
}









share|improve this question
















I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.



struct SE {
SE(char id, char n) : id(id), n(n) {}

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

char id, n;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

LHS lhs;
SE rhs;
};


The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.



For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.



auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }


I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:



SE('a',1);                        // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'


A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.



Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.



Is it possible to obtain that more of the contruction part is produced at compile time?



#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;

// forward declaration
template <typename LHS> struct ME;

struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}

ME<SE> operator,(const SE& r);

size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }

~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

char id, n;
mutable bool outer;
};

template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}

size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }

auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }

~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='n'; cout << b; } }

LHS lhs;
SE rhs;
mutable bool outer;
};

ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }

void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}

int main() {
demo('a',1,'b',1,'c',1);
return 0;
}






c++ c++11 operator-overloading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 6:21







Fabio

















asked Dec 28 '18 at 10:31









FabioFabio

971419




971419








  • 3





    For working code, codereview.stackexchange.com seems more appropriate.

    – Jarod42
    Dec 28 '18 at 10:39











  • "How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

    – YSC
    Dec 28 '18 at 10:41











  • And this is what you do. See Jarod's comment then ;)

    – YSC
    Dec 28 '18 at 10:43














  • 3





    For working code, codereview.stackexchange.com seems more appropriate.

    – Jarod42
    Dec 28 '18 at 10:39











  • "How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

    – YSC
    Dec 28 '18 at 10:41











  • And this is what you do. See Jarod's comment then ;)

    – YSC
    Dec 28 '18 at 10:43








3




3





For working code, codereview.stackexchange.com seems more appropriate.

– Jarod42
Dec 28 '18 at 10:39





For working code, codereview.stackexchange.com seems more appropriate.

– Jarod42
Dec 28 '18 at 10:39













"How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

– YSC
Dec 28 '18 at 10:41





"How to determine if the class is the outermost or not?": you cannot, but you can determine if a class is not the outermost (the constr of ME can alert (inhibit) those AssignExpr they are not the outermost). Your solution is then to trigger evaluation if a class has not received an inhibiting signal.

– YSC
Dec 28 '18 at 10:41













And this is what you do. See Jarod's comment then ;)

– YSC
Dec 28 '18 at 10:43





And this is what you do. See Jarod's comment then ;)

– YSC
Dec 28 '18 at 10:43












1 Answer
1






active

oldest

votes


















1














The general pattern you are following is expression templates. Reading up on how others do it will help.



Usually expression templates use CRTP heavily, and do not store copies.



I believe I see bugs due to the copies.



Generally take T&& and store T& or T&&.



Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.



Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.



I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.






share|improve this answer
























  • Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

    – Fabio
    Jan 3 at 6:09












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957069%2fworking-with-expressions-how-to-minimize-runtime-construction-time%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














The general pattern you are following is expression templates. Reading up on how others do it will help.



Usually expression templates use CRTP heavily, and do not store copies.



I believe I see bugs due to the copies.



Generally take T&& and store T& or T&&.



Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.



Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.



I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.






share|improve this answer
























  • Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

    – Fabio
    Jan 3 at 6:09
















1














The general pattern you are following is expression templates. Reading up on how others do it will help.



Usually expression templates use CRTP heavily, and do not store copies.



I believe I see bugs due to the copies.



Generally take T&& and store T& or T&&.



Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.



Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.



I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.






share|improve this answer
























  • Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

    – Fabio
    Jan 3 at 6:09














1












1








1







The general pattern you are following is expression templates. Reading up on how others do it will help.



Usually expression templates use CRTP heavily, and do not store copies.



I believe I see bugs due to the copies.



Generally take T&& and store T& or T&&.



Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.



Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.



I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.






share|improve this answer













The general pattern you are following is expression templates. Reading up on how others do it will help.



Usually expression templates use CRTP heavily, and do not store copies.



I believe I see bugs due to the copies.



Generally take T&& and store T& or T&&.



Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.



Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.



I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 1 at 18:53









Yakk - Adam NevraumontYakk - Adam Nevraumont

189k21199384




189k21199384













  • Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

    – Fabio
    Jan 3 at 6:09



















  • Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

    – Fabio
    Jan 3 at 6:09

















Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

– Fabio
Jan 3 at 6:09





Hi. I simplified a lot the question and the source code. Indeed my final objective is to achieve that the runtime construction of the final expression is as fast as it could be. It seems to me that your answer touches the right topics, but it is too high level for me to make good use of it. Would you mind elaborating? Thank you.

– Fabio
Jan 3 at 6:09




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957069%2fworking-with-expressions-how-to-minimize-runtime-construction-time%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith