aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc114
1 files changed, 90 insertions, 24 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 77d1faced..9ad0b1a20 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -6,12 +6,15 @@
#include "globals.hh"
#include "eval-inline.hh"
#include "download.hh"
+#include "json.hh"
#include <algorithm>
#include <cstring>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <iostream>
+#include <fstream>
#include <sys/time.h>
#include <sys/resource.h>
@@ -23,6 +26,7 @@
#endif
+using std::cout;
namespace nix {
@@ -1723,10 +1727,10 @@ bool EvalState::eqValues(Value & v1, Value & v2)
}
}
-
void EvalState::printStats()
{
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
+ bool showJsonStats = getEnv("NIX_SHOW_STATS", "0") == "json";
Verbosity v = showStats ? lvlInfo : lvlDebug;
printMsg(v, "evaluation statistics:");
@@ -1741,33 +1745,95 @@ void EvalState::printStats()
auto sum = bEnvs + bLists + bValues + bAttrsets;
- printMsg(v, format(" time elapsed: %1%") % cpuTime);
- printMsg(v, format(" size of a value: %1%") % sizeof(Value));
- printMsg(v, format(" size of an attr: %1%") % sizeof(Attr));
- printMsg(v, format(" environments allocated: %1% (%2% bytes, %3%%%)") % nrEnvs % bEnvs % ((bEnvs*100) / sum));
- printMsg(v, format(" list elements: %1% (%2% bytes %3%%%)") % nrListElems % bLists % ((bLists*100)/sum));
- printMsg(v, format(" list concatenations: %1%") % nrListConcats);
- printMsg(v, format(" values allocated: %1% (%2% bytes %3%%%)") % nrValues % bValues % ((bValues*100)/sum));
- printMsg(v, format(" sets allocated: %1% (%2% bytes %3%%%)") % nrAttrsets % bAttrsets % ((bAttrsets*100)/sum));
- printMsg(v, format(" right-biased unions: %1%") % nrOpUpdates);
- printMsg(v, format(" values copied in right-biased unions: %1%") % nrOpUpdateValuesCopied);
- printMsg(v, format(" symbols in symbol table: %1%") % symbols.size());
- printMsg(v, format(" size of symbol table: %1%") % symbols.totalSize());
- printMsg(v, format(" number of thunks: %1%") % nrThunks);
- printMsg(v, format(" number of thunks avoided: %1%") % nrAvoided);
- printMsg(v, format(" number of attr lookups: %1%") % nrLookups);
- printMsg(v, format(" number of primop calls: %1%") % nrPrimOpCalls);
- printMsg(v, format(" number of function calls: %1%") % nrFunctionCalls);
- printMsg(v, format(" total allocations: %1% bytes") % (bEnvs + bLists + bValues + bAttrsets));
-
- printMsg(v, format(" sets: %1% (%2% each, %3% mb total), attrs-in-sets: %4% (%5% each, %6% mb total)") % nrAttrsets % sizeof(Bindings) % ((nrAttrsets * sizeof(Bindings)) / 1024 / 1024) % nrAttrsInAttrsets % sizeof(Attr) % ((nrAttrsInAttrsets * sizeof(Attr)) / 1024 / 1024));
-
#if HAVE_BOEHMGC
GC_word heapSize, totalBytes;
GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes);
- printMsg(v, format(" current Boehm heap size: %1% bytes") % heapSize);
- printMsg(v, format(" total Boehm heap allocations: %1% bytes") % totalBytes);
#endif
+ if (showJsonStats) {
+ auto outPath = getEnv("NIX_SHOW_STATS_PATH","-");
+ std::fstream fs;
+ if (outPath != "-") {
+ fs.open(outPath, std::fstream::out);
+ printMsg(v, format(" written to: %1%") % outPath);
+ }
+ JSONObject topObj(outPath == "-" ? cout : fs, true);
+ topObj.attr("cpuTime",cpuTime);
+ {
+ auto envs = topObj.object("envs");
+ envs.attr("number", nrEnvs);
+ envs.attr("bytes", bEnvs);
+ }
+ {
+ auto lists = topObj.object("list");
+ lists.attr("elements", nrListElems);
+ lists.attr("bytes", bLists);
+ lists.attr("concats", nrListConcats);
+ }
+ {
+ auto values = topObj.object("values");
+ values.attr("number", nrValues);
+ values.attr("bytes", bValues);
+ }
+ {
+ auto syms = topObj.object("symbols");
+ syms.attr("number", symbols.size());
+ syms.attr("bytes", symbols.totalSize());
+ }
+ {
+ auto sets = topObj.object("sets");
+ sets.attr("number", nrAttrsets);
+ sets.attr("bytes", bAttrsets);
+ }
+ {
+ JSONObject sizes = topObj.object("sizes");
+ sizes.attr("Env", sizeof(Env));
+ sizes.attr("Value", sizeof(Value));
+ sizes.attr("Bindings", sizeof(Bindings));
+ sizes.attr("Attr", sizeof(Attr));
+ }
+ topObj.attr("nrOpUpdates", nrOpUpdates);
+ topObj.attr("nrOpUpdateValuesCopied", nrOpUpdateValuesCopied);
+ topObj.attr("nrThunks", nrThunks);
+ topObj.attr("nrAvoided", nrAvoided);
+ topObj.attr("nrLookups", nrLookups);
+ topObj.attr("nrPrimOpCalls", nrPrimOpCalls);
+ topObj.attr("nrFunctionCalls", nrFunctionCalls);
+#if HAVE_BOEHMGC
+ JSONObject gc = topObj.object("gc");
+ gc.attr("heapSize", heapSize);
+ gc.attr("totalBytes", totalBytes);
+#endif
+ } else {
+ if (getEnv("NIX_SHOW_STATS_PATH","-") != "-") {
+ printError("warning: $NIX_SHOW_STATS_PATH only works in combination with NIX_SHOW_STATS=json");
+ }
+ printMsg(v, format(" time elapsed: %1%") % cpuTime);
+ printMsg(v, format(" size of a value: %1%") % sizeof(Value));
+ printMsg(v, format(" size of an attr: %1%") % sizeof(Attr));
+ printMsg(v, format(" environments allocated: %1% (%2% bytes, %3%%%)") % nrEnvs % bEnvs % ((bEnvs*100) / sum));
+ printMsg(v, format(" list elements: %1% (%2% bytes %3%%%)") % nrListElems % bLists % ((bLists*100)/sum));
+ printMsg(v, format(" list concatenations: %1%") % nrListConcats);
+ printMsg(v, format(" values allocated: %1% (%2% bytes %3%%%)") % nrValues % bValues % ((bValues*100)/sum));
+ printMsg(v, format(" sets allocated: %1% (%2% bytes %3%%%)") % nrAttrsets % bAttrsets % ((bAttrsets*100)/sum));
+ printMsg(v, format(" right-biased unions: %1%") % nrOpUpdates);
+ printMsg(v, format(" values copied in right-biased unions: %1%") % nrOpUpdateValuesCopied);
+ printMsg(v, format(" symbols in symbol table: %1%") % symbols.size());
+ printMsg(v, format(" size of symbol table: %1%") % symbols.totalSize());
+ printMsg(v, format(" number of thunks: %1%") % nrThunks);
+ printMsg(v, format(" number of thunks avoided: %1%") % nrAvoided);
+ printMsg(v, format(" number of attr lookups: %1%") % nrLookups);
+ printMsg(v, format(" number of primop calls: %1%") % nrPrimOpCalls);
+ printMsg(v, format(" number of function calls: %1%") % nrFunctionCalls);
+ printMsg(v, format(" total allocations: %1% bytes") % (bEnvs + bLists + bValues + bAttrsets));
+
+ printMsg(v, format(" sets: %1% (%2% each, %3% mb total), attrs-in-sets: %4% (%5% each, %6% mb total)") % nrAttrsets % sizeof(Bindings) % ((nrAttrsets * sizeof(Bindings)) / 1024 / 1024) % nrAttrsInAttrsets % sizeof(Attr) % ((nrAttrsInAttrsets * sizeof(Attr)) / 1024 / 1024));
+
+#if HAVE_BOEHMGC
+ printMsg(v, format(" current Boehm heap size: %1% bytes") % heapSize);
+ printMsg(v, format(" total Boehm heap allocations: %1% bytes") % totalBytes);
+#endif
+ }
+
if (countCalls) {
v = lvlInfo;