a bit better call stack

This commit is contained in:
VaclavT 2021-10-07 07:19:53 +02:00
parent 6ada537e47
commit f92cefc004
6 changed files with 98 additions and 68 deletions

View File

@ -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

View File

@ -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")

3
ml.cpp
View File

@ -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;

48
ml.h
View File

@ -1,6 +1,5 @@
#pragma once
#include <map>
#include <string>
#include <vector>
@ -94,6 +93,8 @@ private:
// and the environment to run the function in.
typedef MlValue (*Builtin)(std::vector<MlValue>, 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<MlValue> 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<MlValue> list;
MlEnvironment lambda_scope;
friend class MlPerfMon;
};

View File

@ -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<MlValue> &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;
call_stack.push_back(method);
std::string method = function.type == MlValue::LAMBDA ? "lambda" : function.str;
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");

View File

@ -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<MlValue> &args);
void end_method_call();
std::string callstack() const;