I have an array of numbers and I'd like to read them in parallel, with some workers (Promises), having a maximum of workers working simultaneously allowed.
I want to get the result, an array of numbers, through a Promise, when all workers have finished their work.
The order in which numbers are read is not important.
I've written some code which is close to the solution, but the workers, being promises, start their work immediately after being created, (as you can see from the "Active workers" infos printed which contains more items than maxWorkers). So I cannot control how many are actually running together, which is what I want.
What I actually want is to see a maximum of maxWorkers listed in the "Active workers" info.
A worker can create a max of maxWorkersToCreate workers, and the total workers working can be as high as maxWorkers.
This is just a toy example, the real work I have to do is to read in parallel some web resources. This is why I thought to Promises and this is why there is a setTimeout in the code (to simulate an async operation).
Library suggestions are accepted as well.
Object.defineProperty(Array.prototype, 'flat', {
value: function(depth = 1) {
return this.reduce(function(flat, toFlatten) {
return flat.concat((Array.isArray(toFlatten) && (depth - 1)) ? toFlatten.flat(depth - 1) : toFlatten);
}, []);
}
});
const workerManager = new class WorkerManager {
constructor() {
this.workers = [];
}
showWorkers() {
let w = this.workers.filter(function(n){ return n != undefined });
console.log("Active workers:", w);
}
setWorker(name) {
this.workers[name] = name;
}
removeWorker(name) {
delete this.workers[name];
}
}
const MAX = 10;
var numbers = [];
for (var i = 0; i < MAX; i++) {
numbers.push(i);
}
// last position being read from workers
let maxPositionQueued = 0;
// max number of workers working
const maxWorkers = 3;
// max workers a worker can create
const maxWorkersToCreate = 4;
// current number of workers working
let currentWorkers = 0;
function readAll(positionToRead) {
if (currentWorkers > maxWorkers) {
// Rescheduling worker
return new Promise(function(resolve) {
setTimeout(function() {
resolve(readAll(positionToRead));
}, Math.random() * 10 + 10);
});
}
function readNumber() {
return new Promise(function(resolve) {
workerManager.setWorker(positionToRead);
workerManager.showWorkers();
console.log("Reading pos:", positionToRead);
setTimeout(function() {
let result = numbers[positionToRead];
workerManager.removeWorker(positionToRead);
resolve(result);
}, Math.random() * 500 + 1000);
});
}
currentWorkers++;
return readNumber().then(function(response) {
let workers = [];
while (workers.length < maxWorkersToCreate &&
maxPositionQueued < MAX - 1) {
/*
* here I'd like to queue a worker and not start it
* immediately
*/
workers.push(readAll(++maxPositionQueued));
}
currentWorkers--;
return Promise.all([
response,
workers
].flat()).then(function(responses) {
return responses.flat();
});
}); // then reponse END
}
readAll(0).then(function(response) {
console.log("Numbers:", response);
});
Related
I am working on sequential and parallel programming in javascript, I was able to solve sequential programming but didn't have an idea of how to do the same using parallel programming.
For Sequential problem was :
This is an example of sequential processing where it will start at 1 and go till 3 and add 21 to it. Then it will start at 1 and go till 2 and add 10 to it. In the end, start at 1 and go till 4 and add 1 to it.
For Input : 1 3*21#2*10#4*1
output will be :
22
23
24
11
12
2
3
4
5
I solved using below code
function solution(inputData) {
var first = inputData.substring(0, 1);
if(first == 1)
{
//sequential
var strArr = inputData.split(" "); //3*21#2*10#4*1
var strHashSplitArr = strArr[1].split("#"); //3*21 #2*10# 4*1
for(var i=0;i<strHashSplitArr.length;i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var addVal = parseInt(loopInp[1]);
for(var k=1;k<=maxVal;k++)
{
console.log(k+addVal);
}
}
}
}
But now the problem is with parallel programming
Problem:
For example 2, there are 3 processes to start in parallel and numbers are 1, 2 and 3 with delays 100, 20 and 50 consecutively. Here all the processes will start together but a number with less delay will be printed first. Here the number with less delay is 2.So it will print 21,22 in the meantime 50 ms will be achieved and it will print 51 from 3rd number. Now it is mixed with number 1 and prints 101 and so on.
Input : 2 1*100#2*20#3*50
Output should be :
21
22
51
101
52
53
I didn't try using parallels but sorted with milliseconds but couldn't get the expected output.
Here is JSfiddle code for 2nd .. which is giving wrong output (I am not using parallel approach) : https://jsfiddle.net/mahajan344/0u2ka981/
How can I achieve the same output using parallel JavaScript programming?
I think a solution for the problem using setTimeout may be:
function printParallel(val, delay)
{
setTimeout(function()
{
console.log(val);
}, delay);
}
function solution(inputData) {
var first = inputData.substring(0, 1);
var strArr = inputData.split(" ");
var strHashSplitArr = strArr[1].split("#");
for (var i = 0; i < strHashSplitArr.length; i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var modifier = parseInt(loopInp[1]);
if (first == 1)
{
for (var j = 1; j <= maxVal; j++)
{
console.log(j+modifier);
}
}
else if (first == 2)
{
for (var j = 1; j <= maxVal; j++)
{
printParallel(j+modifier, modifier);
}
}
}
}
So you will call solution("1 3*21#2*10#4*1"); and solution("2 1*100#2*20#3*50"); to execute the examples but this won't output as expected because the delay of 100 of number 1 is too big to mix with the printing of number 3.
EDIT:
I think now I understand the goal: yo need to set a timeout between every console.log. This will work as expected:
function printParallel(value, maxVal, modifier)
{
setTimeout(function()
{
console.log(value+modifier);
if (value < maxVal)
{
printParallel(++value, maxVal, modifier)
}
}, modifier);
}
function solution(inputData) {
var first = inputData.substring(0, 1);
var strArr = inputData.split(" ");
var strHashSplitArr = strArr[1].split("#");
for (var i = 0; i < strHashSplitArr.length; i++)
{
var loopInp = strHashSplitArr[i].split("*");
var maxVal = parseInt(loopInp[0]);
var modifier = parseInt(loopInp[1]);
if (first == 1)
{
for (var j = 1; j <= maxVal; j++)
{
console.log(j+modifier);
}
}
else if (first == 2)
{
printParallel(1, maxVal, modifier);
}
}
}
Consider:
async function delay(n) {
return new Promise(r => setTimeout(r, n));
}
async function* asyncRange(a, b, d) {
while (a < b) {
await delay(d);
yield a++;
}
}
async function parallel(...ranges_and_delays) {
let iters = ranges_and_delays.map(t => asyncRange(...t));
while (iters.length) {
await Promise.race(iters.map(async it => {
let v = await it.next();
if (!v.done) {
console.log(v.value)
} else {
iters = iters.filter(k => k !== it)
}
}));
}
}
parallel([1, 5, 700], [10, 13, 500], [200, 205, 600])
The idea is to put range generators in an array, start a race between them and print whatever comes first. Once a generator is exhausted, remove it from the list.
Note that this isn't real parallel computing (which is not possible in Javascript), just an imitation.
You cannot run your code in parallel in Javascript. It is single threaded language. However, you can use browser's web APIs to do work in parallel. For example, making xhr call.
Note: You cannot even run your code in parallel with SetTimeout() as it will only run the code when the call stack is empty. It does not actually run the code in parallel.
To develop an understanding of this, you must understand event loop.
https://www.educative.io/edpresso/what-is-an-event-loop-in-javascript
I'm using the following code to update the state but the Promise.all() array isn't always resolved before the final function is called. Sometimes, the entire array is populated but it usually isn't.
I'm logging the Promise.all() array to the console just so I can see what's happening. What is really peculiar is the state is always updated properly but calling the individual elements in the array often returns "undefined". I need to use the individual elements to create a new array for displaying later which is why I'm accessing them.
Please help me either figure out how to access the array when it's finished updating or a better way to process the entire thing.
class X {
componentDidMount() {
const numTiles = 3;
for (let i = 0; i < numTiles; i++) {
Promise.all([
this.fetchSong(), // returns JSON from SQLite DB
this.fetchArtists(), // returns JSON from SQLite DB
])
.then(values => {
this.testing(values);
});
}
}
testing(arr) {
console.log("arr: ", arr);
console.log("arr[0]: ", arr[0]);
console.log("arr[0].id: ", arr[0].id);
console.log("arr[0].name: ", arr[0].name);
console.log("arr[0].artist: ", arr[0].artist);
console.log("arr[1]: ", arr[1]);
console.log("arr[1][0]: ", arr[1][0]);
console.log("arr[1][1]: ", arr[1][1]);
console.log("arr[1][0].artist: ", arr[1][0].artist);
console.log("arr[1][1].artist: ", arr[1][1].artist);
}
}
Edit: code for fetchSong() and fetchArtists() added.
fetchSong() {
let id = Math.floor(Math.random() * 2000) + 1; // get random number for id
return new Promise((resolve, reject) => {
Bingo.getSong(id).then(song => {
resolve(song);
});
});
}
fetchArtists() {
return new Promise((resolve, reject) => {
let arr = [];
for (let j = 0; j < 2; j++) {
let id = Math.floor(Math.random() * 10) + 1;
Bingo.getArtist(id).then(artist => {
arr.push(artist);
});
resolve(arr);
};
});
}
The console screenshot below shows the Promise.all() array has been populated but the array elements are still missing.
The problem is in the implementation of fetchArtists, which resolved before any of the single-artist-fetching promises were resolved.
I've also simplified fetchSong, but the gist of fetchArtists now is you store the promises that will resolve to single artists, then wait for all of them to resolve. There's no reason to add a .then() there, since as you know, Promise.all() will resolve with an array of resolved values anyhow.
fetchSong() {
const id = Math.floor(Math.random() * 2000) + 1;
return Bingo.getSong(id);
}
fetchArtists() {
const fetchPromises = [];
for (let j = 0; j < 2; j++) {
const id = Math.floor(Math.random() * 10) + 1;
fetchPromises.push(Bingo.getArtist(id));
}
return Promise.all(fetchPromises);
}
I'm working with Node.js since 5 years and from 2 years on big projects with this framework. For two years, I'm confronted to a problem: how to work asynchronously and faster with non-async third party applications who's stacks requests, like MySQL, MongoDB or Apache SolR ?
I'm used to work with promises and to prepared several promises requests, like this:
const promises = []
for (let i = 0; i < 1000; i += 1) {
const promise = mySqlRequest()
promises.push(promise)
}
Promise.all(promises)
.then()
.catch()
This example will work but will send 1000 requests at the same time to MySQL server, who's will stacks these requests and become very slow, will consume very large quantity of RAM.
The best solution is to do only one big request, but in some case it's impossible and I'm forced to make recursive function,
which comes down to be synchronous and slower.
So, what the best way to work fast and asynchronous with Node.js and a stacking third party ?
If sending all requests at once doesn't work and sending them one by one doesn't work either, you'd need something similar to a thread-pool where some arbitrary number of tasks execute simultaneously. This is easily implementable using promises, for example like this:
Promise.pooled = function(arr, num = 5) {
return new Promise(function(resolve, reject) {
var i = -1;
var error = false;
var end = function() {
num--;
if(num === 0) resolve();
}
var next = function() {
if(error) return;
i++;
if(i >= arr.length)
end();
else
arr[i]().then(next).catch(onerr);
}
var onerr = function() {
if(error) return
error = true
reject.call(arguments)
}
for(var j = 0; j < num; j++)
next()
});
}
What this allows you is pass an array of functions as first argument, those functions should take no parameter and return a promise. It will then execute exactly num simultaneously. If one of the promises fail, it will fail its own promise aswell and stop executing (this is changeable easily).
Example:
Promise.after = function(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms)
});
}
Promise.pooled = function(arr, num = 5) {
return new Promise(function(resolve, reject) {
var i = -1;
var error = false;
var end = function() {
num--;
if(num === 0) resolve();
}
var next = function() {
if(error) return;
i++;
if(i >= arr.length)
end();
else
arr[i]().then(next).catch(onerr);
}
var onerr = function() {
if(error) return
error = true
reject.call(arguments)
}
for(var j = 0; j < num; j++)
next()
});
}
var test = [
afterH(1000),
afterH(500),
afterH(800),
afterH(600),
afterH(3000),
afterH(300),
afterH(900),
afterH(2000),
afterH(1500),
afterH(900),
afterH(700),
afterH(600),
afterH(700)
];
// helper function, returns a function which when invoked returns a promise
function afterH(ms) {
return function() {
console.log("Starting one job")
return Promise.after(ms);
}
}
Promise.pooled(test, 3).then(function() {console.log("All jobs finished") }).catch(function() {console.log("Job failed")})
I'm having a hard time trying to understand promises, I'm sure I need to use them for this but I don't know how and other answers don't help me at all.
I'd like to loop over an array, query all the results for each value of the array, then after calculating the average value for these results, add the average in an array. After every iterations, this array is sent as a response.
Here is my code which could help understand me here:
Parse.Cloud.define('getScorePeopleArray', function(request, response) {
var peopleArray = request.params.peoplearray;
var query = new Parse.Query("Scores");
var resultat;
var index, len;
var resultarray = [];
var people;
for (index = 0, len = peopleArray.length; index < len; ++index) {
people = peopleArray[index];
query.equalTo("People",people);
query.find({
success: function(results) {
var sum = 0;
for (var i = 0; i < results.length; ++i) {
sum += results[i].get("Score");
}
resultat = (sum / results.length)*5;
if(!resultat){
resultarray.push("null");
}else{
resultarray.push(resultat);
}
},
error: function() {
response.error("score lookup failed");
}
}).then();
}
response.success(resultarray);
});
Of course response.success is not called when every queries are done, but as soon as possible (since queries are asynchronous if I'm right).
I know I have to change it with promises, but I don't understand at all how this works.
Thanks a lot in advance !
var _ = require('underscore');
Parse.Cloud.define('getScorePeopleArray', function(request, response) {
var peopleArray = request.params.peoplearray; // what is this an array of?
var resultArray = [];
return Parse.Promise.as().then(function() { // this just gets the ball rolling
var promise = Parse.Promise.as(); // define a promise
_.each(peopleArray, function(people) { // use underscore, its better :)
promise = promise.then(function() { // each time this loops the promise gets reassigned to the function below
var query = new Parse.Query("Scores");
query.equalTo("People", people); // is this the right query syntax?
return query.find().then(function(results) { // the code will wait (run async) before looping again knowing that this query (all parse queries) returns a promise. If there wasn't something returning a promise, it wouldn't wait.
var sum = 0;
for (var i = 0; i < results.length; i++) {
sum += results[i].get("Score");
}
var resultat = (sum / results.length) * 5;
if (!resultat){
resultArray.push("null");
} else {
resultArray.push(resultat);
}
return Parse.Promise.as(); // the code will wait again for the above to complete because there is another promise returning here (this is just a default promise, but you could also run something like return object.save() which would also return a promise)
}, function (error) {
response.error("score lookup failed with error.code: " + error.code + " error.message: " + error.message);
});
}); // edit: missing these guys
});
return promise; // this will not be triggered until the whole loop above runs and all promises above are resolved
}).then(function() {
response.success(resultArray); // edit: changed to a capital A
}, function (error) {
response.error("script failed with error.code: " + error.code + " error.message: " + error.message);
});
});
I have a piece of JavaScript code that I am executing using the node.js interpreter.
for(var i = 1; i < LIMIT; i++) {
var user = {
id: i,
name: "MongoUser [" + i + "]"
};
db.users.save(user, function(err, saved) {
if(err || !saved) {
console.log("Error");
} else {
console.log("Saved");
}
});
}
How can I measure the time taken by these database insert operations? I could compute the difference of date values after and before this piece of code but that would be incorrect because of the asynchronous nature of the code.
Use the Node.js console.time() and console.timeEnd():
var i;
console.time("dbsave");
for(i = 1; i < LIMIT; i++){
db.users.save({id : i, name : "MongoUser [" + i + "]"}, end);
}
end = function(err, saved) {
console.log(( err || !saved )?"Error":"Saved");
if(--i === 1){
console.timeEnd("dbsave");
}
};
There is a method that is designed for this. Check out process.hrtime(); .
So, I basically put this at the top of my app.
var start = process.hrtime();
var elapsed_time = function(note){
var precision = 3; // 3 decimal places
var elapsed = process.hrtime(start)[1] / 1000000; // divide by a million to get nano to milli
console.log(process.hrtime(start)[0] + " s, " + elapsed.toFixed(precision) + " ms - " + note); // print message + time
start = process.hrtime(); // reset the timer
}
Then I use it to see how long functions take. Here's a basic example that prints the contents of a text file called "output.txt":
var debug = true;
http.createServer(function(request, response) {
if(debug) console.log("----------------------------------");
if(debug) elapsed_time("recieved request");
var send_html = function(err, contents) {
if(debug) elapsed_time("start send_html()");
response.writeHead(200, {'Content-Type': 'text/html' } );
response.end(contents);
if(debug) elapsed_time("end send_html()");
}
if(debug) elapsed_time("start readFile()");
fs.readFile('output.txt', send_html);
if(debug) elapsed_time("end readFile()");
}).listen(8080);
Here's a quick test you can run in a terminal (BASH shell):
for i in {1..100}; do echo $i; curl http://localhost:8080/; done
Invoking console.time('label') will record the current time in milliseconds, then later calling console.timeEnd('label') will display the duration from that point.
The time in milliseconds will be automatically printed alongside the label, so you don't have to make a separate call to console.log to print a label:
console.time('test');
//some code
console.timeEnd('test'); //Prints something like that-> test: 11374.004ms
For more information, see Mozilla's developer docs on console.time.
Surprised no one had mentioned yet the new built in libraries:
Available in Node >= 8.5, and should be in Modern Browers
https://developer.mozilla.org/en-US/docs/Web/API/Performance
https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#
Node 8.5 ~ 9.x (Firefox, Chrome)
// const { performance } = require('perf_hooks'); // enable for node
const delay = time => new Promise(res=>setTimeout(res,time))
async function doSomeLongRunningProcess(){
await delay(1000);
}
performance.mark('A');
(async ()=>{
await doSomeLongRunningProcess();
performance.mark('B');
performance.measure('A to B', 'A', 'B');
const measure = performance.getEntriesByName('A to B')[0];
// firefox appears to only show second precision.
console.log(measure.duration);
// apparently you should clean up...
performance.clearMarks();
performance.clearMeasures();
// Prints the number of milliseconds between Mark 'A' and Mark 'B'
})();
https://repl.it/#CodyGeisler/NodeJsPerformanceHooks
Node 12.x
https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html
const { PerformanceObserver, performance } = require('perf_hooks');
const delay = time => new Promise(res => setTimeout(res, time))
async function doSomeLongRunningProcess() {
await delay(1000);
}
const obs = new PerformanceObserver((items) => {
console.log('PerformanceObserver A to B',items.getEntries()[0].duration);
// apparently you should clean up...
performance.clearMarks();
// performance.clearMeasures(); // Not a function in Node.js 12
});
obs.observe({ entryTypes: ['measure'] });
performance.mark('A');
(async function main(){
try{
await performance.timerify(doSomeLongRunningProcess)();
performance.mark('B');
performance.measure('A to B', 'A', 'B');
}catch(e){
console.log('main() error',e);
}
})();
For anyone want to get time elapsed value instead of console output :
use process.hrtime() as #D.Deriso suggestion, below is my simpler approach :
function functionToBeMeasured() {
var startTime = process.hrtime();
// do some task...
// ......
var elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
console.log('It takes ' + elapsedSeconds + 'seconds');
}
function parseHrtimeToSeconds(hrtime) {
var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
return seconds;
}
var start = +new Date();
var counter = 0;
for(var i = 1; i < LIMIT; i++){
++counter;
db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
if( err || !saved ) console.log("Error");
else console.log("Saved");
if (--counter === 0)
{
var end = +new Date();
console.log("all users saved in " + (end-start) + " milliseconds");
}
});
}
Old question but for a simple API and light-weight solution; you can use perfy which uses high-resolution real time (process.hrtime) internally.
var perfy = require('perfy');
function end(label) {
return function (err, saved) {
console.log(err ? 'Error' : 'Saved');
console.log( perfy.end(label).time ); // <——— result: seconds.milliseconds
};
}
for (var i = 1; i < LIMIT; i++) {
var label = 'db-save-' + i;
perfy.start(label); // <——— start and mark time
db.users.save({ id: i, name: 'MongoUser [' + i + ']' }, end(label));
}
Note that each time perfy.end(label) is called, that instance is auto-destroyed.
Disclosure: Wrote this module, inspired by D.Deriso's answer. Docs here.
You could also try exectimer. It gives you feedback like:
var t = require("exectimer");
var myFunction() {
var tick = new t.tick("myFunction");
tick.start();
// do some processing and end this tick
tick.stop();
}
// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.myFunction.min()); // minimal tick duration
console.log(t.timers.myFunction.max()); // maximal tick duration
console.log(t.timers.myFunction.mean()); // mean tick duration
console.log(t.timers.myFunction.median()); // median tick duration
[edit] There is an even simpler way now to use exectime. Your code could be wrapped like this:
var t = require('exectimer'),
Tick = t.Tick;
for(var i = 1; i < LIMIT; i++){
Tick.wrap(function saveUsers(done) {
db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
if( err || !saved ) console.log("Error");
else console.log("Saved");
done();
});
});
}
// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.saveUsers.min()); // minimal tick duration
console.log(t.timers.saveUsers.max()); // maximal tick duration
console.log(t.timers.saveUsers.mean()); // mean tick duration
console.log(t.timers.saveUsers.median()); // median tick duration
You can use a wrapper function to easily report the execution time of any existing function.
A wrapper is a used to extend an existing function to do something before and after the existing function's execution - and is a convenient way to compose logic.
Here is an example of using the withDurationReporting wrapper:
// without duration reporting
const doSomethingThatMayTakeAWhile = async (someArg: string, anotherArg: number) => {
/** your logic goes here */
}
// with duration reporting
const doSomethingThatMayTakeAWhileWithReporting = withDurationReporting(
'doSomethingThatMayTakeAWhile',
doSomethingThatMayTakeAWhile
);
// note: you can define the function with duration reporting directly, too
const doSomethingThatMayTakeAWhile = withDurationReporting(
'doSomethingThatMayTakeAWhile',
async (someArg: string, anotherArg: number) => {
/** your logic goes here */
}
)
And here is the wrapper itself:
import { hrtime } from 'process';
const roundToHundredths = (num: number) => Math.round(num * 100) / 100; // https://stackoverflow.com/a/14968691/3068233
/**
* a wrapper which reports how long it took to execute a function, after the function completes
*/
export const withDurationReporting = <R extends any, T extends (...args: any[]) => Promise<R>>(
title: string,
logic: T,
options: {
reportingThresholdSeconds: number;
logMethod: (message: string, metadata?: Record<string, any>) => void;
} = {
reportingThresholdSeconds: 1, // report on anything that takes more than 1 second, by default
logMethod: console.log, // log with `console.log` by default
},
) => {
return (async (...args: Parameters<T>): Promise<R> => {
const startTimeInNanoseconds = hrtime.bigint();
const result = await logic(...args);
const endTimeInNanoseconds = hrtime.bigint();
const durationInNanoseconds = endTimeInNanoseconds - startTimeInNanoseconds;
const durationInSeconds = roundToHundredths(Number(durationInNanoseconds) / 1e9); // https://stackoverflow.com/a/53970656/3068233
if (durationInSeconds >= options.reportingThresholdSeconds)
options.logMethod(`${title} took ${durationInSeconds} seconds to execute`, { title, durationInSeconds });
return result;
}) as T;
};
I designed a simple method for this, using console.time() & console.timeEnd():
measure function definition
function measureRunningTime(func,...args){
const varToString = varObj => Object.keys(varObj)[0]
const displayName = func.name || varToString({ func })
console.time(displayName)
func(...args)
console.timeEnd(displayName)
}
To use it, pass a function without arguments, with arguments binded, or with arguments as the following parameters.
Examples:
let's say I want to check the running time of the simplest searching algorithm - SimpleSearch:
measured function definition (your code here)
const simpleSearch = (array = [1,2,3] ,item = 3) => {
for(let i = 0; i< array.length; i++){
if (array[i] === item) return i;
}
return -1
}
implementation without arguments
measureRunningTime(simpleSearch)
//Prints something like that-> simpleSearch: 0.04ms
implementation with arguments using .bind()
const array = [1,2,3]
const item = 3
measureRunningTime(simpleSearch.bind(null, array, item))
//Prints something like that-> bound simpleSearch: 0.04ms
implementation with arguments without using .bind()
const array = [1,2,3]
const item = 3
measureRunningTime(simpleSearch, array, item)
//Prints something like that-> simpleSearch: 0.04ms
-> Take notice!! this implementation is far from perfect - for example there is no error handling - but it can be used to check the running times of simple algorithms,
Moreover , I'm not an experienced programmer so take everything with a grain of salt 🧂 👌
I had same issue while moving from AWS to Azure
For express & aws, you can already use, existing time() and timeEnd()
For Azure, use this:
https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js
These time() and timeEnd() use the existing hrtime() function, which give high-resolution real time.
Hope this helps.
I need this to be cumulative, and to measure different stuff.
Built these functions:
function startMeasuring(key) {
measureTimers[key] = process.hrtime();
}
function stopMeasuring(key) {
if (!measures[key]) {
measures[key] = 0;
}
let hrtime = process.hrtime(measureTimers[key]);
measures[key] += hrtime[0] + hrtime[1] / 1e9;
measureTimers[key] = null;
}
Usage:
startMeasuring("first Promise");
startMeasuring("first and second Promises");
await new Promise((resolve) => {
setTimeout(resolve, 1400);
});
stopMeasuring("first Promise");
stopMeasuring("first and second Promises");
startMeasuring("first and second Promises");
await new Promise((resolve) => {
setTimeout(resolve, 600);
});
stopMeasuring("first and second Promises");
console.log("Measure Results", measures);
/*
Measusre Results {
setting: 0.00002375,
'first Promise': 1.409392916,
'first and second Promise': 2.015160376
}
*/