Skip to content

Instantly share code, notes, and snippets.

@JohanEngelen
Created February 24, 2023 20:37
Show Gist options
  • Save JohanEngelen/907c7681e4740f82d37fd2f2244ba7bf to your computer and use it in GitHub Desktop.
Save JohanEngelen/907c7681e4740f82d37fd2f2244ba7bf to your computer and use it in GitHub Desktop.
ASCII output of --ftime-trace
// Run using: ldc2 --run format_timetrace.d <your .time-trace file>
// Outputs timetrace.txt in current dir
import std.stdio;
import std.file;
import std.json;
import std.range;
import std.conv;
import std.algorithm;
int main(string[] args) {
if (args.length < 1)
return 1;
auto input_json = read(args[1]).to!string;
auto output_file = File("timetrace.txt", "w");
auto json = parseJSON(input_json);
auto beginningOfTime = json["beginningOfTime"].get!ulong;
auto traceEvents = json["traceEvents"].get!(JSONValue[]);
// Read meta data
JSONValue[] metadata; // "M"
JSONValue[] counterdata; // "C"
JSONValue[] processes; // "X"
foreach (value; traceEvents) {
switch (value["ph"].get!string) {
case "M": metadata ~= value; break;
case "C": counterdata ~= value; break;
case "X": processes ~= value; break;
default: //drop
}
}
output_file.writeln("Timetrace: ", args[1]);
output_file.writeln("Metadata:");
foreach (node; metadata) {
output_file.write(" ");
output_file.writeln(node);
}
// process node = {"ph":"X","name": "Sema1: Module object","ts":26825,"dur":1477,"loc":"<no file>","args":{"detail": "","loc":"<no file>"},"pid":101,"tid":101},
// Sort time processes
multiSort!( q{a["ts"].get!ulong < b["ts"].get!ulong},
q{a["dur"].get!ulong > b["dur"].get!ulong})
(processes);
// Build tree (to get nicer looking structure lines)
static struct Node {
Node[] children;
const JSONValue* json;
ulong last_ts; // represents the last timestamp of this node (i.e. ts + dur)
this(const JSONValue* json, ulong last_ts) {
this.json = json;
this.last_ts = last_ts;
}
}
Node tree = Node(new JSONValue("Tree root"), ulong.max);
Node*[] parent_stack = [&tree]; // each stack item represents the first uncompleted note of that level in the tree
foreach (const ref process; processes) {
auto last_ts = process["ts"].get!ulong + process["dur"].get!ulong;
size_t parent_idx = 0; // index in parent_stack to which this item should be added.
for (size_t i = 0; i < parent_stack.length; i++) {
if (last_ts > parent_stack[i].last_ts) {
// The current process outlasts stack item i. Stop traversing, parent is i-1;
parent_idx = i-1;
parent_stack.length = i;
break;
}
parent_idx = i;
}
parent_stack[parent_idx].children ~= Node(&process, last_ts);
parent_stack ~= &parent_stack[parent_idx].children[$-1];
}
string duration_format_string = "%13.3f ";
output_file.writeln("Duration (ms)");
// Print the tree
void print_node(const Node* node, wchar[] indentstring, bool last_child) {
output_file.writef(duration_format_string, cast(double)(*node.json)["dur"].get!ulong / 1000);
if (last_child)
indentstring[$-1] = '└';
output_file.write(indentstring);
output_file.write("- ", (*node.json)["name"].get!string);
output_file.write(", ", (*node.json)["args"]["detail"].get!string);
output_file.writeln(", ", (*node.json)["args"]["loc"].get!string);
if (last_child)
indentstring[$-1] = ' ';
wchar[] child_indentstring = indentstring ~ " |";
foreach (i, ref child; node.children) {
print_node(&child, child_indentstring, i == node.children.length-1);
}
}
wchar[] indentstring;
//indentstring ~= ""w;
foreach (i, ref child; tree.children) {
print_node(&child, indentstring, false);
}
return 0;
}
@JohanEngelen
Copy link
Author

Thanks @rikkimax . Added to LDC here: ldc-developers/ldc#4335
(the text output indentation string is incorrect in your version, so I used my earlier un-optimized version)

@rikkimax
Copy link

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment