Memoization and knowing how to write a memoize decorator function can be very useful. This is especially true for functions that require intensive processing and recursive functions. In this tutorial, you will learn what memoization is, how to apply it, and how to write a memoize function that can add memoization to other functions. Our memoize function will use closure. If you are not familiar with closures, I recommend you check out my tutorial on closure here: ruclips.net/video/1S8SBDhA7HA/видео.html
hey there Dave, yesterday, was going thru' some tutorial vids on node and express. 2 packages -- eJS and handlebars. apparently intended for same objective. I mean, what they did with eJS in 1 of the vids, the other guy did more or less same[and a little more] with handlebars in the other. wondering which 1 to go for in my upcoming works. much ado about nothing, or is there significant difference[and benefit] betw. these 2 npm packages
If I come across an advanced javascript topic/concept, I will literally search through Dave's tutorials to watch and re-watch because he is one of the best explainers I find so far. The explanations are clear, concise and relatable (how we can possibly apply them). I am coming here after watching his videos on Closures, Prototypes, IIFE, Throttle, Debounce and Currying.
I have one idea to make the memo function even more robust. Usually on large data sets, the cache can grow a lot. A general rule of thumb is to use Map in the occasions when you don't know big the object (cache) can grow. The reason is that as the data size scales, Map substantially outperforms object in insertion, update and deletion operations. Great teaching! I watched all your advanced JavaScrtipt concepts videos and I learned a lot about currying and higher-order functions. Thank you!
I have so much to thank you, now I'm consuming all your videos on many topics, I started my career using Java and many other languages. 2 years ago I decided to work only with JS for both back and front end. but I did started with frameworks like react, nextjs and nestJS. but never really learned the vanilla JS, and I always felt like I wasn't becoming great JS. finally I decided to take time to go back to the fundamentals to advance again. and after covering topics like "Mutable vs Immutable", "Shallow and Deep copy", "Pure Function", "lexical scope" and "Closure" from your videos. suddenly everything makes sense. I feel like it is the key for so many side effects, bugs and issues some developers face. sometimes we believe we know, and I thought I know. but with concepts like lexical scope and closure now I feel like I know exactly what happen and why. Thanks and bless you ;)
Professor Gray, Thanks again for an intuitive tutorial which smacks to the point loud and clear; moreover, the details are explained in a perfect manner for complete understanding. Thanks again Dave for all the hard work. It sure is a major benefit on my side!!
I'm only a beginner in Javascript, but the last example was a stab in the heart. Quickly rewrote it to this extremely more efficient version. It's mindboggling that in such a repetitive computation you would only want to memoize the final call to fib(40), instead of everything in between! const memoize = (fn) => { const cache = {}; return (...args) => { if (args.toString() in cache) { return cache[args.toString()]; } const result = fn(...args); cache[args.toString()] = result; return result; } }; const fib = memoize((num) => { if (num < 2) return num; return fib(num - 1) + fib(num - 2); }); PS: string keys are not great for something that should work with any argument of any type
Excellent video in fact the whole playlist is incredible. I was looking for these advanced concepts. Thank you for explaining in a clear and precise way.
Thanks my favorite teacher for all this hardcoded , i have some suggestions i want to do some tutorial with scratch because i think there is much viewer had not native speaker of english like me , i feel your best in all of your work for that i want to get a universal content , that's Amazing i think ❤❤
Excellent video series Dave! You are a great explainer. Thank you for explaining these intermediate and advance concepts. I hope you will do a video series on design patterns as well. Please consider this.
Thanks for the tutorial. One problem with your memoize function is that if the user input '2' (as string) or 2 (as number), they would receive the same cached output. Which probably could be solved using the JSON.stringify function. Just wanted to point that out in case anyone faced such an issue.
JSON.stringify is a great option here. Nice observation and comment! 💯 I cannot think of a function where I would possibly enter the same parameters as string "2" or number 2 for example, but I know it can happen if you are unsure of the incoming data and haven't cleaned it yet. In the limited use cases for memoize, I would not recommend a memoized function for direct user input before the user data has been verified/cleaned/etc if it could be avoided.
Thanks a lot, about these useful concepts. I'd like to check about the memoizedAddMany(1,2,3,4,5) function. With the arguments (1,2,3,4,5) and (2,3,4,5,1), both of them yield the same answer (but their keys being different), so I think there can still be optimization.
Very nice Dave, I used this concept in multiple languages but I was always referring to it as caching, maybe it would be nice to use the console.time()/console.timeEnd() methods in your comparison, Thanks
While I cannot think of a use case for memoize where I would pass in a function, it might need adjusted to work for that. For an object, JSON.stringify() should be used instead of .toString(). Then, yes it will work for objects.
Nice vid , thanks. if i memoize fibonaci function it self, for example : const fibonaci = (pos) => { const cache = {}; return (function fib(pos) { if (pos in cache) return cache[pos]; if (pos < 2) return pos; cache[pos - 1] = fib(pos - 1); cache[pos - 2] = fib(pos - 2); return cache[pos - 1] + cache[pos - 2]; })(pos); }; remains a pure function right ?! because cache inside the function and it is not a parameter and does not have a side effect
What if the function input is an object. In this case when we stringify we will have [object Object] as a key. How would it be better to memoize in this case?
I would not want to do that. React has many things "under the hood" that make it easier to use than Vanilla JS once you get to where you can think in React. I have a beginners course for React on this channel.
A genuine question if you don't mind. What if we were to apply the .sort() method: _args.sort().toString()_ instead of just _args.toString()_ (8:40) ...so that we wouldn't have to do the computing if an array contained the same elements (but in a different order)? Is it worth it (considering that it's definitely going to impact the Big O of the function)?
Thoughtful question! It just depends on the desired results. You might also consider the JSON.stringify() option mentioned here in the comments, too. I may have mentioned it afterwards in the description as well.
I write it as a constructor function function Memorize(fn) { this.cache = {}; return (...args) => { if (JSON.stringify(args) in this.cache) { return this.cache[JSON.stringify(args)]; } const result = fn(...args); this.cache[JSON.stringify(args)] = result; return result; }; } // Example function fibonacci(n) { return n
Memoization and knowing how to write a memoize decorator function can be very useful. This is especially true for functions that require intensive processing and recursive functions. In this tutorial, you will learn what memoization is, how to apply it, and how to write a memoize function that can add memoization to other functions. Our memoize function will use closure. If you are not familiar with closures, I recommend you check out my tutorial on closure here: ruclips.net/video/1S8SBDhA7HA/видео.html
hey there Dave,
yesterday, was going thru' some tutorial vids on node and express.
2 packages -- eJS and handlebars. apparently intended for same objective. I mean, what they did with eJS in 1 of the vids, the other guy did more or less same[and a little more] with handlebars in the other.
wondering which 1 to go for in my upcoming works. much ado about nothing,
or
is there significant difference[and benefit] betw. these 2 npm packages
If I come across an advanced javascript topic/concept, I will literally search through Dave's tutorials to watch and re-watch because he is one of the best explainers I find so far. The explanations are clear, concise and relatable (how we can possibly apply them). I am coming here after watching his videos on Closures, Prototypes, IIFE, Throttle, Debounce and Currying.
I have one idea to make the memo function even more robust. Usually on large data sets, the cache can grow a lot. A general rule of thumb is to use Map in the occasions when you don't know big the object (cache) can grow. The reason is that as the data size scales, Map substantially outperforms object in insertion, update and deletion operations.
Great teaching! I watched all your advanced JavaScrtipt concepts videos and I learned a lot about currying and higher-order functions. Thank you!
Only you can teach such deep topics with ease... thank you man!
Man... The content quality on this channel... Amazing!
Thank you very much and keep it up!
Thank you, Marshall! 💯
I have so much to thank you, now I'm consuming all your videos on many topics, I started my career using Java and many other languages. 2 years ago I decided to work only with JS for both back and front end. but I did started with frameworks like react, nextjs and nestJS. but never really learned the vanilla JS, and I always felt like I wasn't becoming great JS. finally I decided to take time to go back to the fundamentals to advance again. and after covering topics like "Mutable vs Immutable", "Shallow and Deep copy", "Pure Function", "lexical scope" and "Closure" from your videos. suddenly everything makes sense. I feel like it is the key for so many side effects, bugs and issues some developers face. sometimes we believe we know, and I thought I know. but with concepts like lexical scope and closure now I feel like I know exactly what happen and why.
Thanks and bless you ;)
So glad I could help!
perfect explanation , combine both memoization and decoration at the same time
Professor Gray,
Thanks again for an intuitive tutorial which smacks to the point loud and clear; moreover, the details are explained in a perfect manner for complete understanding. Thanks again Dave for all the hard work. It sure is a major benefit on my side!!
You're very welcome! I'm glad I could help. 💯🚀
I'm only a beginner in Javascript, but the last example was a stab in the heart. Quickly rewrote it to this extremely more efficient version. It's mindboggling that in such a repetitive computation you would only want to memoize the final call to fib(40), instead of everything in between!
const memoize = (fn) => {
const cache = {};
return (...args) => {
if (args.toString() in cache) {
return cache[args.toString()];
}
const result = fn(...args);
cache[args.toString()] = result;
return result;
}
};
const fib = memoize((num) => {
if (num < 2) return num;
return fib(num - 1) + fib(num - 2);
});
PS: string keys are not great for something that should work with any argument of any type
I always return to this channel to learn, repeat and practise 📝
{return great}
Right on! 💯
Excellent video in fact the whole playlist is incredible. I was looking for these advanced concepts. Thank you for explaining in a clear and precise way.
Accept my gratitude for this wonderful content... From your Indian student 🙏
You're welcome!
🚀 Fantastic tutorial on memoization!
Your explanation was clear and concise.
Yes beauty of the memoize function and also the beauty of your concepts and explanation thanks dave
You're welcome!
Thank you for the great video! Finally understand what useMemo is doing, and refreshed JS concepts.
Glad it was helpful!
Amazing teaching style. Just love your videos. Thank you so much.
Thank you for the kind words! 🙏
Thanks my favorite teacher for all this hardcoded , i have some suggestions i want to do some tutorial with scratch because i think there is much viewer had not native speaker of english like me , i feel your best in all of your work for that i want to get a universal content , that's Amazing i think ❤❤
Excellent video series Dave! You are a great explainer. Thank you for explaining these intermediate and advance concepts. I hope you will do a video series on design patterns as well. Please consider this.
Thank you, Deva. 🙏 Great suggestion! 💯
@@DaveGrayTeachesCode Hi Dave! I hope you are doing great. Please create a video series on Design patterns. You are an amazing teacher.
@@vasudev16180 thank you for the kind words and the request! 🙏💯
I like your unique advanced tutorials. Thank you so much. keep going on plz
You're welcome, Zuhair! 🙏
Thanks for the tutorial. One problem with your memoize function is that if the user input '2' (as string) or 2 (as number), they would receive the same cached output. Which probably could be solved using the JSON.stringify function. Just wanted to point that out in case anyone faced such an issue.
JSON.stringify is a great option here. Nice observation and comment! 💯 I cannot think of a function where I would possibly enter the same parameters as string "2" or number 2 for example, but I know it can happen if you are unsure of the incoming data and haven't cleaned it yet. In the limited use cases for memoize, I would not recommend a memoized function for direct user input before the user data has been verified/cleaned/etc if it could be avoided.
I've added a gist with your suggestion using JSON.stringify() 🚀 gist.github.com/gitdagray/fc87981b00386024b0a4a6de940f0a94
Brilliant tutorial , Sir
Awesome,very good explanation
Glad it was helpful!
Thanks Dave, you always surprise us with impressive content
You're welcome Amer 🙏💯
Thanks a lot, about these useful concepts.
I'd like to check about the memoizedAddMany(1,2,3,4,5) function. With the arguments (1,2,3,4,5) and (2,3,4,5,1), both of them yield the same answer (but their keys being different), so I think there can still be optimization.
I think you can do that by sorting the array before storing it as a key in the cache.
So nice to learn from you. Thank you
You're welcome Mahmudul 💯
Very nice Dave,
I used this concept in multiple languages but I was always referring to it as caching,
maybe it would be nice to use the console.time()/console.timeEnd() methods in your comparison,
Thanks
Great idea Ahmad!
Fine, but you better transfort it to string only once and save it in a variable and just pass it instead of transforming it each time ..
awesome as always!
Thank you Aman! 💯
What happens when you pass functions or objects as argument instead of numbers? Will it still work?
While I cannot think of a use case for memoize where I would pass in a function, it might need adjusted to work for that. For an object, JSON.stringify() should be used instead of .toString(). Then, yes it will work for objects.
so it an FP alternative of "proxy design pattern /cash" in OOP
Nice vid , thanks.
if i memoize fibonaci function it self, for example :
const fibonaci = (pos) => {
const cache = {};
return (function fib(pos) {
if (pos in cache) return cache[pos];
if (pos < 2) return pos;
cache[pos - 1] = fib(pos - 1);
cache[pos - 2] = fib(pos - 2);
return cache[pos - 1] + cache[pos - 2];
})(pos);
};
remains a pure function right ?!
because cache inside the function and it is not a parameter and does not have a side effect
Good question, and yes - memoization does not (and should not) change the function being memoized. If it was pure before, it should still be pure.
What if the function input is an object. In this case when we stringify we will have [object Object] as a key. How would it be better to memoize in this case?
You can use JSON.stringify(obj) to convert an object to a string.
Awesome +++++++++++++++++++++++++++++++++
Sir, how can i convert react code to vanillaJS? I need to figure out how react works actually. It's because react makes me regress :/
I would not want to do that. React has many things "under the hood" that make it easier to use than Vanilla JS once you get to where you can think in React. I have a beginners course for React on this channel.
@@DaveGrayTeachesCode It's just to see what's going on in the background. Thanks anyway. By the way, I am in the TS video :))
A genuine question if you don't mind.
What if we were to apply the .sort() method:
_args.sort().toString()_ instead of just _args.toString()_ (8:40)
...so that we wouldn't have to do the computing if an array contained the same elements (but in a different order)?
Is it worth it (considering that it's definitely going to impact the Big O of the function)?
Thoughtful question! It just depends on the desired results. You might also consider the JSON.stringify() option mentioned here in the comments, too. I may have mentioned it afterwards in the description as well.
your decorators tutorial video is inaccessible
I write it as a constructor function
function Memorize(fn) {
this.cache = {};
return (...args) => {
if (JSON.stringify(args) in this.cache) {
return this.cache[JSON.stringify(args)];
}
const result = fn(...args);
this.cache[JSON.stringify(args)] = result;
return result;
};
}
// Example
function fibonacci(n) {
return n
React🗿