From ae02706c71471316b525476ab3a04a872e68fb56 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 07:09:55 -0600 Subject: [PATCH] Approx 12% speedup for function call heavy profile.chai --- .../chaiscript/dispatchkit/dispatchkit.hpp | 76 +++++++++---------- .../chaiscript/language/chaiscript_engine.hpp | 2 +- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 7157e31..489d77f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -377,6 +377,7 @@ namespace chaiscript struct State { std::map > m_functions; + std::map m_function_objects; std::map m_global_objects; Type_Name_Map m_types; std::set m_reserved_words; @@ -553,21 +554,7 @@ namespace chaiscript } // If all that failed, then check to see if it's a function - std::vector funcs = get_function(name); - - if (funcs.empty()) - { - throw std::range_error("Object not known: " + name); - } else { - if (funcs.size() == 1) - { - // Return the first item if there is only one, - // no reason to take the cost of the extra level of dispatch - return const_var(funcs.front()); - } else { - return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); - } - } + return get_function_object(name); } /** @@ -650,9 +637,26 @@ namespace chaiscript } else { return std::vector(); } - } + /// \returns a function object (Boxed_Value wrapper) if it exists + /// \throws std::range_error if it does not + Boxed_Value get_function_object(const std::string &t_name) const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + + const std::map &funs = get_function_objects_int(); + + std::map::const_iterator itr = funs.find(t_name); + + if (itr != funs.end()) + { + return itr->second; + } else { + throw std::range_error("Object not found: " + t_name); + } + } + /** * Return true if a function exists */ @@ -696,31 +700,11 @@ namespace chaiscript /// /// Get a map of all functions that can be seen from a scripting context /// - std::map get_scripting_functions() const + std::map get_function_objects() const { chaiscript::detail::threading::shared_lock l(m_mutex); - std::vector > rets; - - const std::map > &functions = get_functions_int(); - - std::map retval; - - for (std::map >::const_iterator itr = functions.begin(); - itr != functions.end(); - ++itr) - { - if (itr->second.size() == 1) - { - // Return the first item if there is only one, - // no reason to take the cost of the extra level of dispatch - retval.insert(std::make_pair(itr->first, const_var(itr->second.front()))); - } else { - retval.insert(std::make_pair(itr->first, Boxed_Value(Const_Proxy_Function(new Dispatch_Function(itr->second))))); - } - } - - return retval; + return get_function_objects_int(); } @@ -914,6 +898,16 @@ namespace chaiscript return *(m_stack_holder->stacks.back()); } + const std::map &get_function_objects_int() const + { + return m_state.m_function_objects; + } + + std::map &get_function_objects_int() + { + return m_state.m_function_objects; + } + const std::map > &get_functions_int() const { return m_state.m_functions; @@ -1045,6 +1039,8 @@ namespace chaiscript std::map >::iterator itr = funcs.find(t_name); + std::map &func_objs = get_function_objects_int(); + if (itr != funcs.end()) { std::vector &vec = itr->second; @@ -1060,11 +1056,15 @@ namespace chaiscript vec.push_back(t_f); std::stable_sort(vec.begin(), vec.end(), &function_less_than); + func_objs[t_name] = Boxed_Value(Const_Proxy_Function(new Dispatch_Function(vec))); } else { std::vector vec; vec.push_back(t_f); funcs.insert(std::make_pair(t_name, vec)); + func_objs[t_name] = const_var(t_f); } + + } mutable chaiscript::detail::threading::shared_mutex m_mutex; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 7586186..1da74f4 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -322,7 +322,7 @@ namespace chaiscript m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, boost::ref(m_engine)), "is_type"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, boost::ref(m_engine)), "type_name"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, boost::ref(m_engine)), "function_exists"); - m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_functions, boost::ref(m_engine)), "get_functions"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, boost::ref(m_engine)), "get_functions"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, boost::ref(m_engine)), "get_objects"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name");