193 lines
6.9 KiB
C++
193 lines
6.9 KiB
C++
#include "util/util.h"
|
|
#include "util/gc_stat.h"
|
|
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
|
|
namespace nasal {
|
|
|
|
void gc_stat::init() {
|
|
for (i64 i = 0; i < GC_TYPE_SIZE; i++) {
|
|
object_size[i] = 0;
|
|
alloc_count[i] = 0;
|
|
gc_cycle_trigger_count[i] = 0;
|
|
}
|
|
|
|
total_mark_count = 0;
|
|
total_sweep_count = 0;
|
|
|
|
total_mark_time = 0;
|
|
total_sweep_time = 0;
|
|
|
|
max_mark_time = 0;
|
|
max_sweep_time = 0;
|
|
}
|
|
|
|
f64 gc_stat::gc_time_ms() const {
|
|
const auto den = std::chrono::high_resolution_clock::duration::period::den;
|
|
return ((total_mark_time + total_sweep_time) * 1000.0) / den;
|
|
}
|
|
|
|
f64 gc_stat::avg_time_ms() const {
|
|
u64 total_gc_cycle = 0;
|
|
for (i64 i = 0; i < GC_TYPE_SIZE; i++) {
|
|
total_gc_cycle += gc_cycle_trigger_count[i];
|
|
}
|
|
return gc_time_ms() / total_mark_count;
|
|
}
|
|
|
|
f64 gc_stat::avg_mark_time_ms() const {
|
|
const auto den = std::chrono::high_resolution_clock::duration::period::den;
|
|
return (total_mark_time * 1000.0) / den / total_mark_count;
|
|
}
|
|
|
|
f64 gc_stat::avg_sweep_time_ms() const {
|
|
const auto den = std::chrono::high_resolution_clock::duration::period::den;
|
|
return (total_sweep_time * 1000.0) / den / total_sweep_count;
|
|
}
|
|
|
|
f64 gc_stat::max_mark_time_ms() const {
|
|
const auto den = std::chrono::high_resolution_clock::duration::period::den;
|
|
return (max_mark_time * 1000.0) / den;
|
|
}
|
|
|
|
f64 gc_stat::max_sweep_time_ms() const {
|
|
const auto den = std::chrono::high_resolution_clock::duration::period::den;
|
|
return (max_sweep_time * 1000.0) / den;
|
|
}
|
|
|
|
void gc_stat::dump_info() const {
|
|
util::windows_code_page_manager wm;
|
|
wm.set_utf8_output();
|
|
|
|
using std::left;
|
|
using std::setw;
|
|
using std::setfill;
|
|
using std::setprecision;
|
|
|
|
const char* used_table_name[] = {
|
|
"object type",
|
|
"gc cycle",
|
|
"alloc count",
|
|
"object count",
|
|
"detail",
|
|
"time spend",
|
|
"gc time",
|
|
"avg time",
|
|
"max gc",
|
|
"max mark",
|
|
"max sweep"
|
|
};
|
|
const char* name[] = {
|
|
"string",
|
|
"vector",
|
|
"hashmap",
|
|
"function",
|
|
"upvalue",
|
|
"ghost",
|
|
"coroutine",
|
|
"namespace"
|
|
};
|
|
|
|
// calculate max indent length
|
|
usize indent = 0;
|
|
for (auto tname : used_table_name) {
|
|
auto len = strlen(tname);
|
|
indent = indent<len? len:indent;
|
|
}
|
|
for (auto n : name) {
|
|
auto len = strlen(n);
|
|
indent = indent<len? len:indent;
|
|
}
|
|
for(u32 i = 0; i < GC_TYPE_SIZE; ++i) {
|
|
auto len = std::to_string(gc_cycle_trigger_count[i]).length();
|
|
indent = indent<len? len:indent;
|
|
len = std::to_string(alloc_count[i]).length();
|
|
indent = indent<len? len:indent;
|
|
len = std::to_string(object_size[i]).length();
|
|
indent = indent<len? len:indent;
|
|
}
|
|
|
|
auto indent_string = std::string("──");
|
|
for(usize i = 0; i < indent; ++i) {
|
|
indent_string += "─";
|
|
}
|
|
|
|
const auto first_line = "╭" + indent_string + "┬" +
|
|
indent_string + "┬" +
|
|
indent_string + "┬" +
|
|
indent_string + "╮";
|
|
const auto second_line = "├" + indent_string + "┼" +
|
|
indent_string + "┼" +
|
|
indent_string + "┼" +
|
|
indent_string + "┤";
|
|
const auto mid_line = "├" + indent_string + "┼" +
|
|
indent_string + "┴" +
|
|
indent_string + "┴" +
|
|
indent_string + "┤";
|
|
const auto another_mid_line = "├" + indent_string + "┼" +
|
|
indent_string + "─" +
|
|
indent_string + "─" +
|
|
indent_string + "┤";
|
|
const auto last_line = "╰" + indent_string + "┴" +
|
|
indent_string + "─" +
|
|
indent_string + "─" +
|
|
indent_string + "╯";
|
|
|
|
std::clog << "\n" << first_line << "\n";
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "object type";
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << "gc cycle";
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << "alloc count";
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << "object count";
|
|
std::clog << " │\n" << second_line << "\n" << std::internal;
|
|
|
|
for (u32 i = 0; i < GC_TYPE_SIZE; ++i) {
|
|
if (!gc_cycle_trigger_count[i] &&
|
|
!alloc_count[i] &&
|
|
!object_size[i]) {
|
|
continue;
|
|
}
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << name[i];
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << gc_cycle_trigger_count[i];
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << alloc_count[i];
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << object_size[i];
|
|
std::clog << " │\n" << std::internal;
|
|
}
|
|
std::clog << mid_line << "\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "detail";
|
|
std::clog << " │ " << left << setw(indent) << setfill(' ') << "time spend";
|
|
std::clog << " " << left << setw(indent) << setfill(' ') << " ";
|
|
std::clog << " " << left << setw(indent) << setfill(' ') << " ";
|
|
std::clog << " │\n" << another_mid_line << "\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "gc time";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << gc_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg time";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << avg_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg mark";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << avg_mark_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg sweep";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << avg_sweep_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "max mark";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << max_mark_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << "│ " << left << setw(indent) << setfill(' ') << "max sweep";
|
|
std::clog << " │ " << setw(indent-3) << setprecision(4) << max_sweep_time_ms() << " ms";
|
|
std::clog << setw(indent*2+7) << " " << "│\n";
|
|
|
|
std::clog << last_line << "\n" << std::internal;
|
|
|
|
wm.restore_code_page();
|
|
}
|
|
|
|
} |