basic version of profiler class
This commit is contained in:
parent
a931661608
commit
56407f3516
|
|
@ -14,7 +14,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-stack_size -Wl,0x1000
|
|||
# otool -lV build/ml | grep stack
|
||||
|
||||
# set(CMAKE_CXX_FLAGS "-Wall -Wextra")
|
||||
# set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
|
||||
include_directories(/usr/local/opt/openssl/include ${CMAKE_SOURCE_DIR}/clib ${CMAKE_SOURCE_DIR} )
|
||||
|
||||
|
|
@ -30,6 +30,7 @@ set(SOURCE
|
|||
ml_date.cpp
|
||||
ml_string.cpp
|
||||
ml_util.cpp
|
||||
ml_profiler.cpp
|
||||
clib/csvparser.cpp
|
||||
clib/sslclient.cpp
|
||||
clib/json11.cpp
|
||||
|
|
|
|||
30
ml.cpp
30
ml.cpp
|
|
@ -4,6 +4,7 @@
|
|||
#include "ml_date.h"
|
||||
#include "ml_string.h"
|
||||
#include "ml_util.h"
|
||||
#include "ml_profiler.h"
|
||||
|
||||
#include "clib/csvparser.h"
|
||||
#include "clib/sslclient.h"
|
||||
|
|
@ -710,6 +711,8 @@ 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);
|
||||
|
||||
return function.apply(
|
||||
args,
|
||||
env
|
||||
|
|
@ -1651,7 +1654,7 @@ namespace builtin {
|
|||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double, std::milli> time_span = t2 - t1;
|
||||
|
||||
std::cout << args[0].as_string() << " " << time_span.count() << " ms" << std::endl;
|
||||
std::cerr << args[0].as_string() << " " << time_span.count() << " ms" << std::endl;
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
|
@ -1718,20 +1721,15 @@ bool MlEnvironment::has(std::string name) const {
|
|||
|
||||
// Get the value associated with this name in this scope
|
||||
MlValue MlEnvironment::get(const std::string &name) const {
|
||||
// Meta operations
|
||||
if (name == "eval") return MlValue("eval", builtin::eval);
|
||||
if (name == "type") return MlValue("type", builtin::get_type_name);
|
||||
if (name == "parse") return MlValue("parse", builtin::parse);
|
||||
|
||||
// Special forms
|
||||
if (name == "do") return MlValue("do", builtin::do_block);
|
||||
if (name == "if") return MlValue("if", builtin::if_then_else);
|
||||
if (name == "define") return MlValue("define", builtin::define);
|
||||
if (name == "do") return MlValue("do", builtin::do_block);
|
||||
if (name == "for") return MlValue("for", builtin::for_loop);
|
||||
if (name == "while") return MlValue("while", builtin::while_loop);
|
||||
if (name == "scope") return MlValue("scope", builtin::scope);
|
||||
if (name == "quote") return MlValue("quote", builtin::quote);
|
||||
if (name == "defun") return MlValue("defun", builtin::defun);
|
||||
if (name == "define") return MlValue("define", builtin::define);
|
||||
if (name == "lambda") return MlValue("lambda", builtin::lambda);
|
||||
if (name == "benchmark") return MlValue("benchmark", builtin::benchmark);
|
||||
|
||||
|
|
@ -1743,6 +1741,11 @@ MlValue MlEnvironment::get(const std::string &name) const {
|
|||
if (name == ">=") return MlValue(">=", builtin::greater_eq);
|
||||
if (name == "<=") return MlValue("<=", builtin::less_eq);
|
||||
|
||||
// Meta operations
|
||||
if (name == "eval") return MlValue("eval", builtin::eval);
|
||||
if (name == "type") return MlValue("type", builtin::get_type_name);
|
||||
if (name == "parse") return MlValue("parse", builtin::parse);
|
||||
|
||||
// Arithmetic operations
|
||||
if (name == "+") return MlValue("+", builtin::sum);
|
||||
if (name == "-") return MlValue("-", builtin::subtract);
|
||||
|
|
@ -1862,7 +1865,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
// help
|
||||
if (cmdOptionExists(argv, argv + argc, "-h")) {
|
||||
std::cout << "Usage:\n\t-h print this help\n\t-f source_file - executes code in file\n\t-c code - runs passed code\n\t-i runs repl\n\t-b skip stdlib loading\n\t-v prints version string\n\n";
|
||||
std::cout << "Usage:\n\t-h print this help\n\t-f source_file - executes code in file\n\t-c code - runs passed code\n\t-i runs repl\n\t-b skip stdlib loading\n\t-p prints profile info at the end\n\t-v prints version string\n\n";
|
||||
return 0;
|
||||
}
|
||||
// version
|
||||
|
|
@ -1870,6 +1873,9 @@ int main(int argc, char *argv[]) {
|
|||
std::cout << VERSION << std::endl;
|
||||
return 0;
|
||||
}
|
||||
// performance monitor on
|
||||
if (cmdOptionExists(argv, argv + argc, "-p"))
|
||||
MlPerfMon::instance().turnOn();
|
||||
// passed code
|
||||
if (cmdOptionExists(argv, argv + argc, "-c")) {
|
||||
std::vector<std::string> codes = getCmdOption(argv, argc, "-c");
|
||||
|
|
@ -1885,11 +1891,15 @@ int main(int argc, char *argv[]) {
|
|||
repl(env);
|
||||
}
|
||||
|
||||
MlPerfMon::instance().print_results();
|
||||
|
||||
return 0;
|
||||
|
||||
} catch (MlError &e) {
|
||||
std::cerr << e.description() << std::endl;
|
||||
} catch (std::runtime_error &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#include "ml_profiler.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
void MlPerfMon::turnOn() {
|
||||
perfOn = true;
|
||||
|
||||
}
|
||||
|
||||
void MlPerfMon::add_method_call(const std::string &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});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MlPerfMon::print_results() {
|
||||
if (perfOn) {
|
||||
std::cerr << std::endl << std::endl << "Call Frequency" << std::endl;
|
||||
|
||||
using callcount = std::pair<std::string, long>;
|
||||
|
||||
std::vector<callcount> v(begin(calls_counter), end(calls_counter));
|
||||
std::sort(std::begin(v), std::end(v), [](const callcount& a, const callcount& b) { return a.second > b.second; });
|
||||
|
||||
int i {0};
|
||||
for(auto &p : v) {
|
||||
// TODO when method name longer than 15 chars, here it crashes
|
||||
p.first.insert(p.first.end(), 15 - p.first.size(), ' ');
|
||||
std::cerr << p.first << " " << p.second << std::endl;
|
||||
|
||||
i++;
|
||||
if (i > 10) break;
|
||||
}
|
||||
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "ml.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class MlPerfMon {
|
||||
|
||||
private:
|
||||
MlPerfMon() : perfOn(false) {};
|
||||
|
||||
public:
|
||||
|
||||
// https://stackoverflow.com/questions/43523509/simple-singleton-example-in-c
|
||||
static MlPerfMon& instance(){
|
||||
static MlPerfMon instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void turnOn();
|
||||
|
||||
void add_method_call(const std::string &method);
|
||||
void print_results();
|
||||
|
||||
private:
|
||||
bool perfOn;
|
||||
std::unordered_map<std::string, long> calls_counter;
|
||||
};
|
||||
Loading…
Reference in New Issue