Reputation: 431
I'm trying to improve code performance and after years of coding find myself confused about some fundamentals. Of course we essentially have things that need go in order (async functions) and things in parallel (just normal functions which are synchronous ). I read about promise.all and setTimeout type examples and tried to make a big function rewritten with all these fundamentals and was throwing async on every function and when I finished it was way slower than it was before and now am realizing that async is not as prevalent as I thought but am confused.
If I have the function
function count(n){
let num = 0
for(let i = n; i--;){
num++
}
return num
}
and throw in like 140000000 then that is going to take a second to complete. If I need the returned value for the rest of a function to continue I was thinking I would need to await the response so that I could use the response going forward
async function doSomething(){
const one = await count(140000000)
const two = count(one)
return two
}
async function count(n){
let num = 0
for(let i = n; i--;){
num++
}
return num
}
But in fact I think its not so much as a value I need to pass into the next function for it to work so its basically fine without awaiting the response because its basically sending a function as the parameter like
async function doSomething(){
const two = count(count(140000000))
return two
}
function count(n){
let num = 0
for(let i = n; i--;){
num++
}
return num
}
Similarly like synchronous type tasks I thought I would need to use Promise.all to speed things up for concurrently running functions and the functions it takes should be async because it returns a promise that way like
async function parent2(){
console.log('start')
console.time('ALL')
const numsToCount = [ 140000000, 170000000, 240000000 ]
const res = await countNums2(numsToCount)
// do other stuff with res
const fin = count(res[0])
console.timeEnd('ALL')
console.log('end', fin)
}
async function countNums2(numsToCount){
let countedNumsPromises = []
for(let i = numsToCount.length; i--;){
countedNumsPromises.push(count2(numsToCount[i]))
}
return Promise.all(countedNumsPromises)
}
async function count2(n){
let num = 0
for(let i = n; i--;){
num++
}
return num
}
But then again realized I didnt really need promise.all even though its three functions that take some time but can be run together and could just do
function parent1(){
console.log('start')
console.time('ALL')
const numsToCount = [ 140000000, 170000000, 240000000 ]
const res = countNums(numsToCount)
console.timeEnd('ALL')
console.log('end', res)
}
function countNums(numsToCount){
let countedNums = []
for(let i = numsToCount.length; i--;){
countedNums.push(count(numsToCount[i]))
}
return countedNums
}
function count(n){
let num = 0
for(let i = n; i--;){
num++
}
return num
}
And when you start nesting things like 3 times and more complex things obviously is confusing as well but perhaps trying to get some of these more basic understandings figured out will help with everything. Like doing
const parents = [
{name: 'Jon', pets: ['dodo', 'goofy']},
{name: 'Tammy', pets: ['gigi', 'laffy', 'bigbird']},
{name: 'Tom', pets: ['ralphy', 'goose']},
]
const res = await Promise.all(parents.map(async parent => {
const res2 = await Promise.all(parent.pets.map(async pet => {
...
}
}
Also would a wait function like in many examples be different than just a slow count function?
async function doSomething(){
await Promise.all([wait(1000),wait(2000),wait(1500)])
wait(1000)
}
async function wait(ms){
return new Promise((resolve) => setTimeout(resolve, ms));
}
So maybe I'm throwing a lot at you here but basically how do I implement synchronous programming and what not for speed properly and what is proper use of async and promise.all vs just passing all the functions into each other as needed and letting the functions figure out all the waiting on the previous function. Also side note I seemed to find that map reduce and filter were not perhaps the fastest because you would be looping over the same data multiple times so unlike that example above I was trying to stick to more for loops but yeah I don't want that to distract from answering question but that is direction I'm trying to go.
Upvotes: 0
Views: 419
Reputation: 84912
Promises (and thus async/await) aren't a tool to take synchronous code and speed it up. When you create a promise it's usually because you're not calculating anything at all, but instead are waiting for something external to happen.
For example, you might be waiting for a network response to get back, or you might be waiting for a timer to elapse, or waiting for someone to press a key. You can't do any work while this is happening, so instead you create a Promise and then stop running any code. Since javascript is single threaded, stopping running your code is important to let other code start running, including the browser's normal page-painting code.
Promises are objects with .then
function on it. You can call .then
and pass in a function to tell it "hey, when you're done waiting, please call this function". async
/await
just simplifies the syntax for working with promises: an async
function will automatically create a promise, and await
ing a promise will automatically call .then
on it.
With that in mind: The examples you gave don't have anything to do with async await. You have a bunch of synchronous computations, and are not waiting for anything external. Slapping await on a map function or a for loop will have no effect, other than to confuse your coworkers and very slightly increase runtime.
Upvotes: 1