From 89186a86c8b4425ddc788b35bc1818fd5803eb2b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 29 Aug 2009 19:19:31 +0000 Subject: [PATCH] speed up operator calls by about 10% by reducing Proxy_Function copies and such --- .../chaiscript/dispatchkit/dispatchkit.hpp | 9 ++++++- .../dispatchkit/proxy_functions.hpp | 24 ++++++++++++----- .../chaiscript/language/chaiscript_eval.hpp | 26 +++++++++---------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 5e1ea71..42fd3f1 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -86,7 +86,7 @@ namespace chaiscript virtual Boxed_Value operator()(const std::vector ¶ms) { - return dispatch(m_funcs, params); + return dispatch(m_funcs.begin(), m_funcs.end(), params); } virtual std::vector get_param_types() const @@ -371,6 +371,13 @@ namespace chaiscript m_reserved_words.insert(name); } + Boxed_Value call_function(const std::string &t_name, const std::vector ¶ms) + { + std::pair::const_iterator, std::multimap::const_iterator> range + = m_functions.equal_range(t_name); + + return dispatch(range.first, range.second, params); + } private: /** diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b291b06..1324965 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -410,17 +410,16 @@ namespace chaiscript * each function against the set of parameters, in order, until a matching * function is found or throw dispatch_error if no matching function is found */ - Boxed_Value dispatch(const std::vector > &funcs, + template + Boxed_Value dispatch(InItr begin, InItr end, const std::vector &plist) { - for (std::vector >::const_iterator itr = funcs.begin(); - itr != funcs.end(); - ++itr) + while (begin != end) { try { - if (itr->second->filter(plist)) + if (begin->second->filter(plist)) { - return (*itr->second)(plist); + return (*begin->second)(plist); } } catch (const bad_boxed_cast &) { //parameter failed to cast, try again @@ -430,9 +429,22 @@ namespace chaiscript //guard failed to allow the function to execute, //try again } + ++begin; } + throw dispatch_error(); } + + /** + * Take a vector of functions and a vector of parameters. Attempt to execute + * each function against the set of parameters, in order, until a matching + * function is found or throw dispatch_error if no matching function is found + */ + Boxed_Value dispatch(const std::vector > &funcs, + const std::vector &plist) + { + return dispatch(funcs.begin(), funcs.end(), plist); + } } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index fb93800..b2cc688 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -125,13 +125,13 @@ namespace chaiscript try { if (lhs.is_unknown()) { - retval = dispatch(ss.get_function("clone"), Param_List_Builder() << retval); + retval = ss.call_function("clone", Param_List_Builder() << retval); } Param_List_Builder plb; plb << lhs; plb << retval; try { - retval = dispatch(ss.get_function(node->children[i+1]->text), plb); + retval = ss.call_function(node->children[i+1]->text, plb); } catch(const dispatch_error &){ throw Eval_Error("Mismatched types in equation", node->children[i+1]); @@ -155,7 +155,7 @@ namespace chaiscript plb << eval_token(ss, node->children[i]); plb << retval; try { - retval = dispatch(ss.get_function(node->children[i+1]->text), plb); + retval = ss.call_function(node->children[i+1]->text, plb); } catch(const dispatch_error &){ throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]); @@ -235,7 +235,7 @@ namespace chaiscript plb << eval_token(ss, node->children[i + 1]); try { - retval = dispatch(ss.get_function(node->children[i]->text), plb); + retval = ss.call_function(node->children[i]->text, plb); } catch(const dispatch_error &){ throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]); @@ -260,7 +260,7 @@ namespace chaiscript plb << retval; plb << eval_token(ss, node->children[i]); try { - retval = dispatch(ss.get_function("[]"), plb); + retval = ss.call_function("[]", plb); } catch(std::out_of_range &) { throw Eval_Error("Out of bounds exception", node); @@ -286,7 +286,7 @@ namespace chaiscript plb << Boxed_Value(-1.0); try { - return dispatch(ss.get_function("*"), plb); + return ss.call_function("*", plb); } catch(std::exception &){ throw Eval_Error("Can not find appropriate negation", node->children[0]); @@ -323,7 +323,7 @@ namespace chaiscript plb << retval; try { - return dispatch(ss.get_function(node->children[0]->text), plb); + return ss.call_function(node->children[0]->text, plb); } catch(std::exception &){ throw Eval_Error("Can not find appropriate prefix", node->children[0]); @@ -339,12 +339,12 @@ namespace chaiscript unsigned int i; try { - retval = dispatch(ss.get_function("Vector"), Param_List_Builder()); + retval = ss.call_function("Vector", Param_List_Builder()); if (node->children.size() > 0) { for (i = 0; i < node->children[0]->children.size(); ++i) { try { Boxed_Value tmp = eval_token(ss, node->children[0]->children[i]); - dispatch(ss.get_function("push_back"), Param_List_Builder() << retval << tmp); + ss.call_function("push_back", Param_List_Builder() << retval << tmp); } catch (const dispatch_error &) { throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]); @@ -365,7 +365,7 @@ namespace chaiscript template Boxed_Value eval_inline_range(Eval_System &ss, TokenPtr node) { try { - return dispatch(ss.get_function("generate_range"), Param_List_Builder() + return ss.call_function("generate_range", Param_List_Builder() << eval_token(ss, node->children[0]->children[0]->children[0]) << eval_token(ss, node->children[0]->children[0]->children[1])); } @@ -383,12 +383,12 @@ namespace chaiscript unsigned int i; try { - retval = dispatch(ss.get_function("Map"), Param_List_Builder()); + retval = ss.call_function("Map", Param_List_Builder()); for (i = 0; i < node->children[0]->children.size(); ++i) { try { Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]); - Boxed_Value slot = dispatch(ss.get_function("[]"), Param_List_Builder() << retval << key); - dispatch(ss.get_function("="), Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1])); + Boxed_Value slot = ss.call_function("[]", Param_List_Builder() << retval << key); + ss.call_function("=", Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1])); } catch (const dispatch_error &) { throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);