Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
13
rated 0 times [  19] [ 6]  / answers: 1 / hits: 15932  / 7 Years ago, wed, may 24, 2017, 12:00:00

I'm trying to write a function that measures the execution time of another function:



export class Profiler {
public measureSyncFunc(fn: () => any): Promise<number> {
return new Promise<number>((resolve, reject) => {
let elapsed = 0;

let intervalId = window.setInterval(() => {
elapsed += 1; // this is never called
}, 1);

this.execFunc(fn)
.then((result: any) => {
window.clearInterval(intervalId);
resolve(elapsed);
});
});
}

private execFunc(fn: () => any): Promise<any> {
return new Promise<any>((resolve, reject) => {
resolve(fn());
});
}
}


Then I use it like that:



let array = generateRandomArray(100000);

instance.measureSyncFunc(bubbleSort(array))
.then((elapsed: number) => {
console.log(`end session: ${elapsed} seconds`);
resolve();
});


The bubbleSort function is synchronous and it takes several seconds to complete.
See code here:



The result in the console is end session: 0 seconds because the interval callback is never called.



Do you know how I can make it called ?
Thank you very much guys !


More From » typescript

 Answers
5

If the functions you want to measure will always be synchronous there's really no need to involve promises.



Since the function you want to test takes parameters you it's best to to wrap it in an arrow function in order to be able to call it with another context and not have to manage it's parameters yourself.



Something simple like this will do just fine.



function measure(fn: () => void): number {
let start = performance.now();
fn();
return performance.now() - start;
}

function longRunningFunction(n: number) {
for (let i = 0; i < n; i++) {
console.log(i);
}
}

let duration = measure(() => {
longRunningFunction(100);
});

console.log(`took ${duration} ms`);




If you want to measure the time it takes an async function (if it returns a promise) to resolve you can easily change the code to something like this:



function measurePromise(fn: () => Promise<any>): Promise<number> {
let onPromiseDone = () => performance.now() - start;

let start = performance.now();
return fn().then(onPromiseDone, onPromiseDone);
}

function longPromise(delay: number) {
return new Promise<string>((resolve) => {
setTimeout(() => {
resolve('Done');
}, delay);
});
}

measurePromise(() => longPromise(300))
.then((duration) => {
console.log(`promise took ${duration} ms`);
});




Note: This solution uses the ES6 Promise, if you are using something else you might have to adapt it but the logic should be the same.



You can see both examples working in the playground here.


[#57676] Monday, May 22, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckaylab

Total Points: 311
Total Questions: 120
Total Answers: 93

Location: Montenegro
Member since Thu, Jun 16, 2022
2 Years ago
;