diff --git a/Readme.md b/Readme.md index b25aaef..344b91f 100644 --- a/Readme.md +++ b/Readme.md @@ -85,11 +85,10 @@ utils/local_install.sh - compare - needed for sorting, cmp ignore case - regexp match, regexp tokens - date support + - local-time - convert epoch to local time - decode-universal-time (http://www.lispworks.com/documentation/HyperSpec/Body/f_dec_un.htm) - env functions - get-env, set-env; set-env cannot be implemented in stdlib.lsp, because popen is in fact subshell -- add include-stdlib function for other libs in stdlib dir (during startup stdlib.lsp is loaded only) -- syntax highlighting do VS Code #### Performance - define is one of most frequent callee, when in scope with very few vars, lookup sequentially @@ -97,7 +96,7 @@ utils/local_install.sh - push_back - repeatedly without reserving size - range - with for(int i...) and reserving result size can be 3times faster on (range 1 10000) - mini_sprintf - unnecesary copying between vector and list -- (do, scope ..) repeatedly assign to acc +- (do, scope, cond ..) repeatedly assign to acc ### Links diff --git a/debug.lsp b/debug.lsp index 024862d..92833e4 100644 --- a/debug.lsp +++ b/debug.lsp @@ -1,14 +1,63 @@ -(define a 20) -(cond - ((> a 30) (print "a > 30")) - ((> a 20) (print "a > 20")) - (1 (print "a je" a))) -(define a 25) -(cond - ((> a 30) (print "a > 30")) - ((> a 20) (print "a > 20")) - (1 (print "a je" a))) +(defun find-with-val-sublist (lst name) + (do + ; (print "list:" lst " name:" name) + (define found_val nil) + (define i 0) + + (while (and (>= i 0) (< i (len lst))) + (define e (index lst i)) + ; (print "testing element:" e " first e:" (first e)) + (if (= (type (first e)) "list") + (do + (set! found_val (find-with-val-sublist (first e) name)) + (if (!= found_val nil) (set! i -1)) + ) + ; else + (do + ;(print "compare" (first e) " with " name) + (if (= name (first e)) + (do + ; (print "found" name) + (set! found_val (second e)) (set! i -1) + ) + ; else + (if (= (type (second e)) "list") + (do (set! found_val (find-with-val-sublist (second e) name)) + (if (!= found_val nil) + (set! i -1) + ) + ) + (define i (inc i)) + ) + ) + ) + ) + ) + found_val + )) + + + + +(define str "{\"date_from\":\"2021-10-05\",\"date_to\":\"2021-10-05\",\"earnings\":{\"2021-10-05\":{\"stocks\":[{\"importance\":5,\"symbol\":\"PEP\",\"date\":\"2021-10-05\",\"time\":\"06:00:00\",\"title\":\"PepsiCo\"},{\"importance\":0,\"symbol\":\"SAR\",\"date\":\"2021-10-05\",\"time\":\"16:00:00\",\"title\":\"Saratoga Investment\"}],\"day\":\"Today\",\"month\":\"October\",\"year\":\"2021\",\"date_number\":\"05\",\"selected_copy\":\"PEP and SAR reporting Today\",\"deselected_copy\":\"PEP and SAR reporting Today\"}}}") +(define parsed_json (parse-json str)) +;(print parsed_json "\n") + +(define stocks (find-with-val-sublist parsed_json "stocks")) +(print stocks) +(for s stocks + (print s) + (print (find-with-val-sublist parsed_json "date")) +) + + + +;; (define a 25) +;; (cond +;; ((> a 30) (print "a > 30")) +;; ((> a 20) (print "a > 20")) +;; (1 (print "a je" a))) ;; (define csv_date (str-to-date "01/01/2021" "%m/%d/%Y")) ;; (date-to-str 3141583200 "%m/%d/%Y") diff --git a/ml.cpp b/ml.cpp index 50e7766..01ab178 100644 --- a/ml.cpp +++ b/ml.cpp @@ -726,8 +726,7 @@ MlValue MlValue::eval(MlEnvironment &env) { for (size_t i = 0; i < args.size(); i++) args[i] = args[i].eval(env); - MlPerfMon::instance().add_method_call( - function.type == LAMBDA ? "lambda" : function.str); + MlPerfMon::instance().add_method_call(function, args); res = function.apply(args, env); MlPerfMon::instance().end_method_call(); return res; diff --git a/ml.h b/ml.h index 64d8ee0..4983ed3 100644 --- a/ml.h +++ b/ml.h @@ -1,6 +1,5 @@ #pragma once - #include #include #include @@ -94,6 +93,8 @@ private: // and the environment to run the function in. typedef MlValue (*Builtin)(std::vector, MlEnvironment &); +// friend class +class MlPerfMon; class MlValue { public: @@ -140,29 +141,15 @@ public: MlValue eval(MlEnvironment &env); bool is_builtin() const; - bool is_number() const; - bool is_string() const; - bool is_list() const; - // Get the boolean value of this value. bool as_bool() const; - - // Get this item's integer value long as_int() const; - - // Get this item's floating point value double as_float() const; - - // Get this item's string value std::string as_string() const; - - // Get this item's atom value std::string as_atom() const; - - // Get this item's list value std::vector as_list() const; // Push an item to the end of this list @@ -172,13 +159,8 @@ public: MlValue pop(); - // Cast this to an integer value MlValue cast_to_int() const; - - // Cast this to a floating point value MlValue cast_to_float() const; - - // Cast this to a string MlValue cast_to_string() const; @@ -207,24 +189,26 @@ public: private: enum { - QUOTE, - ATOM, - INT, - FLOAT, - LIST, - STRING, - LAMBDA, - BUILTIN, - NIL + QUOTE, + ATOM, + INT, + FLOAT, + LIST, + STRING, + LAMBDA, + BUILTIN, + NIL } type; union { - long i; - double f; - Builtin b; + long i; + double f; + Builtin b; } stack_data; std::string str; std::vector list; MlEnvironment lambda_scope; + + friend class MlPerfMon; }; diff --git a/ml_profiler.cpp b/ml_profiler.cpp index 27cc6eb..fe14572 100644 --- a/ml_profiler.cpp +++ b/ml_profiler.cpp @@ -16,41 +16,40 @@ void MlPerfMon::turnOn() { start_time = std::chrono::high_resolution_clock::now(); } -void MlPerfMon::add_method_call(const std::string &method) { - std::thread::id this_id = std::this_thread::get_id(); +void MlPerfMon::add_method_call(const MlValue &function, const std::vector &args) { // only main thread is logged, to prevent mixing from others threads so lock not needed - if (main_thread_id != this_id) - return; + if (main_thread_id != std::this_thread::get_id()) return; + + std::string method = function.type == MlValue::LAMBDA ? "lambda" : function.str; - call_stack.push_back(method); - - if (perfOn) { - auto search = calls_counter.find(method); - if (search != calls_counter.end()) { - calls_counter[method] = search->second + 1; - } else { - calls_counter.insert({method, 1}); - } + std::string args_string; + for (size_t i = 0; i < args.size() && args_string.size() < 64; i++) { + args_string.append(" "); + args_string.append(args[i].display()); } + if (args_string.size() > 64) + args_string = args_string.substr(0, 62) + ".."; // TODO introduce constant here + + call_stack.push_back("(" + method + args_string + ")"); + + if (perfOn) + calls_counter[method]++; } void MlPerfMon::end_method_call() { - std::thread::id this_id = std::this_thread::get_id(); // only main thread is looged, to prevent mixing from others threads so lock not needed - if (main_thread_id != this_id) - return; + if (main_thread_id != std::this_thread::get_id()) return; - if (!call_stack.empty()){ + if (!call_stack.empty()) call_stack.pop_back(); - } } std::string MlPerfMon::callstack() const { - std::string cs {"call stack:\n"}; + std::string cs {"\ncall stack:\n"}; int cnt = 0; for (auto it = call_stack.rbegin(); it != call_stack.rend() && cnt < call_stack_max_methods; ++it, ++cnt) - cs.append( std::string(*it) + "\n"); // << std::endl; + cs.append(" " + std::string(*it) + "\n"); // << std::endl; if (call_stack.size() > call_stack_max_methods) cs.append("next " + std::to_string(call_stack.size() - call_stack_max_methods) + " entries skipped..\n"); diff --git a/ml_profiler.h b/ml_profiler.h index d374458..734d775 100644 --- a/ml_profiler.h +++ b/ml_profiler.h @@ -30,7 +30,7 @@ public: void turnOn(); - void add_method_call(const std::string &method); + void add_method_call(const MlValue &function, const std::vector &args); void end_method_call(); std::string callstack() const;