From 0411ed137169c436f55cd494d0d6483766d0df85 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Sat, 17 Oct 2020 11:38:24 -0400 Subject: [PATCH] parallelized agegender operations --- README.md | 17 ++++++++++------- src/index.js | 22 ++++++++++++++++------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index eda782d2..bb1a62db 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ There are multiple ways to use `Human` library, pick one that suits you: - `dist/human.esm-nobundle.js`: ESM format non-minified bundle without TFJS for Browsers - `dist/human.cjs`: CommonJS format non-minified bundle without TFJS for NodeJS -All versions include `sourcemap` +All versions include `sourcemap` and build `manifest` Defaults: ```json @@ -348,12 +348,15 @@ result = { } ], performance = { // performance data of last execution for each module measuredin miliseconds - body, - hand, - face, - agegender, - emotion, - total, + config, // time to parse configuration + load, // time to load models + sanity, // time for input verification + body, // model time + hand, // model time + face, // model time + agegender, // model time + emotion, // model time + total, // end to end time } } ``` diff --git a/src/index.js b/src/index.js index a8c41cd3..12e81434 100644 --- a/src/index.js +++ b/src/index.js @@ -89,36 +89,46 @@ async function load(userConfig) { async function detect(input, userConfig = {}) { state = 'config'; + const perf = {}; + let timeStamp; + + timeStamp = now(); config = mergeDeep(defaults, userConfig); + perf.config = Math.trunc(now() - timeStamp); // sanity checks + timeStamp = now(); state = 'check'; const error = sanity(input); if (error) { log(error, input); return { error }; } + perf.sanity = Math.trunc(now() - timeStamp); // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve) => { + const timeStart = now(); + // check number of loaded models const loadedModels = Object.values(models).filter((a) => a).length; if (loadedModels === 0) log('Human library starting'); // configure backend + timeStamp = now(); if (tf.getBackend() !== config.backend) { state = 'backend'; log('Human library setting backend:', config.backend); await tf.setBackend(config.backend); await tf.ready(); } + perf.body = Math.trunc(now() - timeStamp); // load models if enabled + timeStamp = now(); state = 'load'; await load(); - - const perf = {}; - let timeStamp; + perf.load = Math.trunc(now() - timeStamp); if (config.scoped) tf.engine().startScope(); @@ -164,8 +174,9 @@ async function detect(input, userConfig = {}) { timeStamp = now(); const emotionData = config.face.emotion.enabled ? await emotion.predict(face.image, config) : {}; perf.emotion = Math.trunc(now() - timeStamp); + + // dont need face anymore face.image.dispose(); - delete face.image; // calculate iris distance // iris: array[ bottom, left, top, right, center ] const iris = (face.annotations.leftEyeIris && face.annotations.rightEyeIris) @@ -191,8 +202,7 @@ async function detect(input, userConfig = {}) { if (config.scoped) tf.engine().endScope(); analyze('End Scope:'); - // combine and return results - perf.total = Object.values(perf).reduce((a, b) => a + b); + perf.total = Math.trunc(now() - timeStart); resolve({ face: faceRes, body: poseRes, hand: handRes, performance: perf }); }); }