benchmarking: Adding nim benchmark and qml wallet benchmark

This commit is contained in:
Alex Jbanca 2024-06-24 18:36:13 +03:00
parent f78eced9e7
commit 886ea9df1c
No known key found for this signature in database
GPG Key ID: 6004079575C21C5D
9 changed files with 62 additions and 12 deletions

View File

@ -1,5 +1,6 @@
import NimQml, json, strutils, chronicles, json_serialization import NimQml, json, strutils, chronicles, json_serialization, strutils
import ../eventemitter import ../eventemitter
import dev/benchmark as benchmark
include types include types
@ -65,6 +66,13 @@ QtObject:
proc receiveChroniclesLogEvent(self: SignalsManager, signal: string) {.slot.} = proc receiveChroniclesLogEvent(self: SignalsManager, signal: string) {.slot.} =
self.processSignal(signal, allowLogging=false) self.processSignal(signal, allowLogging=false)
proc logEvent(self: SignalsManager, logStr: string) {.slot.} =
if "benchmark start" in logStr:
benchmark.markCallsOfInterest = true
if "benchmark end" in logStr:
benchmark.markCallsOfInterest = false
info "QML logEvent", data = logStr
proc decode(self: SignalsManager, jsonSignal: JsonNode): Signal = proc decode(self: SignalsManager, jsonSignal: JsonNode): Signal =
let signalString = jsonSignal{"type"}.getStr let signalString = jsonSignal{"type"}.getStr
var signalType: SignalType var signalType: SignalType

View File

@ -1,6 +1,8 @@
import json, json_serialization, stew/shims/strformat, chronicles import json, json_serialization, stew/shims/strformat, chronicles
import status_go import status_go
import response_type import response_type
import dev/benchmark
import std/times
export response_type export response_type
@ -25,6 +27,10 @@ proc makePrivateRpcCall*(
raise newException(RpcException, "db closed due to profile migration") raise newException(RpcException, "db closed due to profile migration")
try: try:
debug "NewBE_callPrivateRPC", rpc_method=methodName debug "NewBE_callPrivateRPC", rpc_method=methodName
let cpuTime = cpuTime()
defer: registerDuration(methodName, cpuTime, cpuTime())
let rpcResponseRaw = status_go.callPrivateRPC($inputJSON) let rpcResponseRaw = status_go.callPrivateRPC($inputJSON)
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode]) result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
if(not result.error.isNil): if(not result.error.isNil):
@ -77,7 +83,7 @@ proc callPrivateRPC*(
proc callPrivateRPCNoDecode*( proc callPrivateRPCNoDecode*(
methodName: string, payload = %* [] methodName: string, payload = %* []
): string {.raises: [RpcException].} = ): string {.raises: [RpcException, Exception].} =
let inputJSON = %* { let inputJSON = %* {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": methodName, "method": methodName,

View File

@ -1,4 +1,4 @@
import times, macros, strutils, locks, algorithm import times, macros, strutils, locks, algorithm, std/exitprocs, std/locks
# benchmark measure execution time of block of code. # benchmark measure execution time of block of code.
# usage: # usage:
# import os, strutils, times # import os, strutils, times
@ -45,6 +45,8 @@ type
numRuns*: int numRuns*: int
totalTime*: float totalTime*: float
procName*: cstring procName*: cstring
numRunsOnMainThread*: int
callOfInterest*: bool
ProcBenchmarkPtr* = ptr ProcBenchmark ProcBenchmarkPtr* = ptr ProcBenchmark
@ -53,11 +55,13 @@ type
len*: int len*: int
maxLen*: int maxLen*: int
BenchmarkResult = tuple[procName: string, numRuns: int, totalTime: float, weight: float] BenchmarkResult = tuple[procName: string, numRuns: int, totalTime: float, weight: float, numRunsOnMainThread: int, callOfInterest: bool]
var var
lock: Lock lock: Lock
benchmarkResults: ptr SharedProcBenchmarkArr benchmarkResults: ptr SharedProcBenchmarkArr
threadId: int
markCallsOfInterest*: bool = false
# Forward declarations # Forward declarations
proc registerDuration*(name: string, startTime: float, endTime: float) {.gcsafe.} proc registerDuration*(name: string, startTime: float, endTime: float) {.gcsafe.}
@ -70,7 +74,8 @@ proc writeToFile(resultsToWrite: seq[BenchmarkResult])
proc resultCmp(x, y: BenchmarkResult): int proc resultCmp(x, y: BenchmarkResult): int
# End of forward declarations # End of forward declarations
addQuitProc(quitCallback) exitprocs.addExitProc(quitCallback)
threadId = getThreadId()
macro benchmarkProc*(procDef: untyped): untyped = macro benchmarkProc*(procDef: untyped): untyped =
procDef.expectKind(nnkProcDef) procDef.expectKind(nnkProcDef)
@ -96,6 +101,9 @@ proc registerDuration*(name: string, startTime: float, endTime: float) {.gcsafe.
if benchmarkResults.data[i].procName == name.cstring: if benchmarkResults.data[i].procName == name.cstring:
benchmarkResults.data[i].numRuns += 1 benchmarkResults.data[i].numRuns += 1
benchmarkResults.data[i].totalTime += endTime - startTime benchmarkResults.data[i].totalTime += endTime - startTime
if getThreadId() == threadId:
benchmarkResults.data[i].numRunsOnMainThread += 1
benchmarkResults.data[i].callOfInterest = markCallsOfInterest or benchmarkResults.data[i].callOfInterest
found = true found = true
if found: if found:
break break
@ -113,6 +121,13 @@ proc registerDuration*(name: string, startTime: float, endTime: float) {.gcsafe.
newProcBenchmark.procName = namePtr newProcBenchmark.procName = namePtr
newProcBenchmark.numRuns = 1 newProcBenchmark.numRuns = 1
newProcBenchmark.totalTime = endTime - startTime newProcBenchmark.totalTime = endTime - startTime
if getThreadId() == threadId:
newProcBenchmark.numRunsOnMainThread = 1
else:
newProcBenchmark.numRunsOnMainThread = 0
newProcBenchmark.callOfInterest = markCallsOfInterest
benchmarkResults.data[benchmarkResults.len] = newProcBenchmark benchmarkResults.data[benchmarkResults.len] = newProcBenchmark
benchmarkResults.len += 1 benchmarkResults.len += 1
@ -156,7 +171,7 @@ proc aggregateData(): seq[BenchmarkResult] =
withLock lock: withLock lock:
for i in 0 ..< benchmarkResults.len: for i in 0 ..< benchmarkResults.len:
totalWeight += benchmarkResults.data[i].totalTime totalWeight += benchmarkResults.data[i].totalTime
result.add(($(benchmarkResults.data[i].procName), benchmarkResults.data[i].numRuns, benchmarkResults.data[i].totalTime, 0.0)) result.add(($(benchmarkResults.data[i].procName), benchmarkResults.data[i].numRuns, benchmarkResults.data[i].totalTime, 0.0, benchmarkResults.data[i].numRunsOnMainThread, benchmarkResults.data[i].callOfInterest))
result.sort(resultCmp) result.sort(resultCmp)
for i in 0 ..< result.len: for i in 0 ..< result.len:
@ -171,13 +186,15 @@ proc writeToFile(resultsToWrite: seq[BenchmarkResult]) =
except: except:
echo "Could not open file procBenchmark.txt for writing" echo "Could not open file procBenchmark.txt for writing"
return return
file.writeLine("Procedure, Number of runs, Total time in ms, Avg time in ms, Weight") file.writeLine("Procedure, Number of runs, Total time in ms, Avg time in ms, Weight, Number of runs on main thread, Call of interest")
for entry in resultsToWrite: for entry in resultsToWrite:
file.writeLine(entry.procName & file.writeLine(entry.procName &
"," & $entry.numRuns & "," & $entry.numRuns &
"," & $(entry.totalTime * 1000) & "," & $(entry.totalTime * 1000) &
"," & $((entry.totalTime / entry.numRuns.float) * 1000) & "," & $((entry.totalTime / entry.numRuns.float) * 1000) &
"," & $(entry.weight * 100) & "%") "," & $(entry.weight * 100) & "%" &
"," & $(entry.numRunsOnMainThread) &
"," & $(entry.callOfInterest))
file.close() file.close()
proc resultCmp(x, y: BenchmarkResult): int = proc resultCmp(x, y: BenchmarkResult): int =

View File

@ -202,6 +202,7 @@ proc mainProc() =
signalsManagerQObjPointer = cast[pointer](statusFoundation.signalsManager.vptr) signalsManagerQObjPointer = cast[pointer](statusFoundation.signalsManager.vptr)
keycardServiceQObjPointer = cast[pointer](appController.keycardService.vptr) keycardServiceQObjPointer = cast[pointer](appController.keycardService.vptr)
setupRemoteSignalsHandling() setupRemoteSignalsHandling()
registerLogHandler(signalsManagerQObjPointer)
info fmt("Version: {APP_VERSION}") info fmt("Version: {APP_VERSION}")
info fmt("Commit: {GIT_COMMIT}") info fmt("Commit: {GIT_COMMIT}")

View File

@ -1152,8 +1152,10 @@ Item {
} }
if (activeSectionType === Constants.appSection.communitiesPortal) if (activeSectionType === Constants.appSection.communitiesPortal)
return Constants.appViewStackIndex.communitiesPortal return Constants.appViewStackIndex.communitiesPortal
if (activeSectionType === Constants.appSection.wallet) if (activeSectionType === Constants.appSection.wallet) {
print ("benchmark start")
return Constants.appViewStackIndex.wallet return Constants.appViewStackIndex.wallet
}
if (activeSectionType === Constants.appSection.browser) if (activeSectionType === Constants.appSection.browser)
return Constants.appViewStackIndex.browser return Constants.appViewStackIndex.browser
if (activeSectionType === Constants.appSection.profile) if (activeSectionType === Constants.appSection.profile)
@ -1287,6 +1289,7 @@ Item {
sendModalPopup: sendModal sendModalPopup: sendModal
networkConnectionStore: appMain.networkConnectionStore networkConnectionStore: appMain.networkConnectionStore
appMainVisible: appMain.visible appMainVisible: appMain.visible
Component.onCompleted: print ("benchmark end")
} }
onLoaded: { onLoaded: {
item.resetView() item.resetView()

View File

@ -104,6 +104,8 @@ DOS_API void DOS_CALL dos_qguiapplication_exec(void);
/// \note This method was created because status-go has a non-QT event loop /// \note This method was created because status-go has a non-QT event loop
DOS_API void DOS_CALL dos_signal(DosQObject *vptr, const char *signal, const char *slot); DOS_API void DOS_CALL dos_signal(DosQObject *vptr, const char *signal, const char *slot);
DOS_API void DOS_CALL dos_register_log_handler(DosQObject *vptr);
DOS_API DosQNetworkConfigurationManager *DOS_CALL dos_qncm_create(); DOS_API DosQNetworkConfigurationManager *DOS_CALL dos_qncm_create();
DOS_API char * DOS_CALL dos_plain_text(char* htmlString); DOS_API char * DOS_CALL dos_plain_text(char* htmlString);

View File

@ -114,6 +114,7 @@ class QMLNetworkAccessFactory : public QQmlNetworkAccessManagerFactory
}; };
QString QMLNetworkAccessFactory::tmpPath = ""; QString QMLNetworkAccessFactory::tmpPath = "";
QObject* log_handler = nullptr;
QNetworkAccessManager* QMLNetworkAccessFactory::create(QObject* parent) QNetworkAccessManager* QMLNetworkAccessFactory::create(QObject* parent)
{ {
@ -211,9 +212,13 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break; break;
default: default:
fprintf(stderr, "Default: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); fprintf(stderr, "!Default: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break; break;
} }
if (log_handler != nullptr) {
QMetaObject::invokeMethod(log_handler, "logEvent", Qt::QueuedConnection, Q_ARG(QString, QStringLiteral("%1 (%2:%3, %4)").arg(localMsg.constData()).arg(file).arg(context.line).arg(function)));
}
} }
void dos_qguiapplication_create() void dos_qguiapplication_create()
@ -1101,6 +1106,14 @@ void dos_signal(::DosQObject *vptr, const char *signal, const char *slot) //
QMetaObject::invokeMethod(qobject, slot_copy.c_str(), Qt::QueuedConnection, Q_ARG(QString, signal_copy.c_str())); QMetaObject::invokeMethod(qobject, slot_copy.c_str(), Qt::QueuedConnection, Q_ARG(QString, signal_copy.c_str()));
} }
void dos_register_log_handler(::DosQObject *vptr)
{
log_handler = static_cast<QObject *>(vptr);
QObject::connect(log_handler, &QObject::destroyed, []() {
log_handler = nullptr;
});
}
void dos_qmetaobject_delete(::DosQMetaObject *vptr) void dos_qmetaobject_delete(::DosQMetaObject *vptr)
{ {
auto factory = static_cast<DOS::DosIQMetaObjectHolder *>(vptr); auto factory = static_cast<DOS::DosIQMetaObjectHolder *>(vptr);

2
vendor/nimqml vendored

@ -1 +1 @@
Subproject commit 20d4db12bb40dcf1c549ab3149ca0b4b791e90b7 Subproject commit 3040c233fc9ad2c7affe584e3fcc735aa6fae190

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 891300a758c7ed19d2d53428afba0dd2d79ad251 Subproject commit 3c99701812ebaac5b0749a7960869bd01ba9c3ef