Is the COST of JavaScript’s GC REALLY that high?

  Рет қаралды 89,805

SimonDev

SimonDev

11 ай бұрын

How much overhead is there really for garbage collection, is it as high as so many people say it is?
My Courses: simondev.teachable.com/
Support me on Patreon: / simondevyt
Follow me on:
Twitter: / iced_coffee_dev
Instagram: / beer_and_code
Garbage Collection is often cited as a major source of performance problems in JavaScript. In this vdeo, we explore garbage collection a bit, and try to understand when and how the overhead is high and when it isn't.
Links:
en.wikipedia.org/wiki/Tracing...
v8.dev/blog/free-garbage-coll...
v8.dev/blog/trash-talk

Пікірлер: 202
@GreenFox1505
@GreenFox1505 11 ай бұрын
Minor Note: WASD is not the "Doom Keys". Doom used arrow keys. WASD was created by the winner of a Quake tournament, who rebound his controls to WASD+Mouse. It very quickly became the industry standard.
@simondev758
@simondev758 11 ай бұрын
Neat!
@the-pink-hacker
@the-pink-hacker 11 ай бұрын
But can WASD run doom?
@kodyduvall349
@kodyduvall349 11 ай бұрын
That is a cool fact. Thanks for sharing!
@RiversJ
@RiversJ 11 ай бұрын
If you redo the bindings from outside the process but that isn't for doves or the faint of heart if you've never done something like that. Though i suspect some guide might exist somewhere.
@sunnohh
@sunnohh 11 ай бұрын
Thats actually a incorrect meme, wasd plus mouselook was common, intended and pretty normal going back to the launch shareware demo start menu. There are many videos on the topic even. Maybe even an entire channel.
@preston7376
@preston7376 11 ай бұрын
Every code review that someone criticizes me making too many intermediate local variables/objects for performance, I link them a Generational GC paper. Now I'm just going to link them this video. Nice work!
@BosonCollider
@BosonCollider 10 ай бұрын
+1. Also, the thing that *does* become more expensive is mutating a pointer from an old object to a newly object. If an old object is updated to point to a new one, that reference should aim to statistically last as long as the old object, because the GC has to do a bunch of extra bookmarking for this case. If you have a data structure where that's only going to be true 50% of the time a purely functional approach might end up doing better than an in-place updating approach. I noticed that when making pairing heaps in languages with generational GC where the functional version outperformed the in-place version.
@HyuLilium
@HyuLilium 10 ай бұрын
Depends where you're doing it. If you're doing it in an app that evolves often and where it's important to make it easy to maintain and understand, premature optimizations like that are the root of a lot of evils.
@Sssanbo
@Sssanbo 6 ай бұрын
On larger single page experiences , i ve always run into memory issues and its not fun to try and track down, I find , atleast for me that treating it like a C++ program is the best way . I try and force deallocation , delete, set to null . THis has never hurt me and what surprises me is just how much better performance I get.
@simondev758
@simondev758 6 ай бұрын
Yeah, there's really no downside to just kinda spelling things out for the GC.
@d2teisen
@d2teisen 11 ай бұрын
@SimonDev, just a quick note: whenever you create a new object and put random stuff in it, it does matter if you do the same random stuff or new ones, and it makes a difference if you use a single object and keep changed that instance. An other long forgotten javascript feature that you might want to test is the prototype chain. I think there is a Netflix medium blog post about it, as they reduced gc calls and memory consumption with not changing the actual object but markint it as a prototype for a new one. Hope you make a new video about those :)
@kephas-media
@kephas-media 11 ай бұрын
Yes, so GC will clear out any objects that don't have a reference to them, or a reference connected to the root. Which makes sense. In gaming, this rule is respected by creating object pools for bullets or items you plan on creating multiple times
@wileysneak
@wileysneak 11 ай бұрын
i cannot find this article anywhere, do you have a searchable term?
@radvilardian740
@radvilardian740 11 ай бұрын
I am smelling ThePrimeagen
@Super7fly
@Super7fly 2 күн бұрын
I wrote that blog post you talk about at 3:30! Really nice summary and exploration of GC in this video. About "manual" GC, there's an optimisation called pre-tenuring, which attempts to figure out which allocation sites create long-lived objects and allocate them directly into old-space. Malloc implementations still have to do book-keeping to manage lists of free chunks and reduce fragmentation, so while there isn't "GC", there is still memory management overhead (though not nearly as much). Something interesting to keep in mind with measurement is that reducing GC time can cause trade-offs in non-GC time, e.g. allocation can end up slower or faster depending on fragmentation, memory access can be faster/slower due to cache locality. Check out the background threads in that chrome tracing view and you'll see a lot more GC happening in the background too! Cheers
@emanuellandeholm5657
@emanuellandeholm5657 3 ай бұрын
I'm a Python programmer. GC is the price I pay for convenience and rapid prototyping. The other cost is the global mutex, which kind of forces you to separate your tasks into processes and use async. Before Python, I used languages like Bash, Emacs Lisp and Perl. Microsoft Basic V2 for the Commodore 64 had a really nasty GC which would freeze up your bread box for minutes. :) I'm trained to fear the GC, and I program accordingly. Before those languages, I used machine code, assembler and C. I've found that memory management in these languages is not really radically different from GC languages, except for the fact that it's explicit and you can have leaks. You always have to think about the life time of your objects.
@volbla
@volbla 11 ай бұрын
I ported some svgs to the desmos graphing calculator to play in sequence as an animation. I noticed some significant hiccups in firefox that were absent in chrome, and this seems to be caused by major gc pauses. This was of course a very inefficient way to go about it. Using a general purpose graphing tool only to draw and fill hundreds of bezier curves, which the browser could just as well do directly with the svg files. This wasn't designed for performance, but it was kind of interesting to see a subtle difference between browsers.
@loucadufault6549
@loucadufault6549 11 ай бұрын
Learn so much from each video. I work with Node so it’s cool seeing these deep dives into core parts of the engine. One thing that would be cool would be to try and unravel the actual execution of async code. Things like how functions are wrapped with promises, how the execution bounces back between frames upon hitting an await, asynchronous context (AsyncLocalStorage) etc.
@ariasalehi5665
@ariasalehi5665 11 ай бұрын
Fantastic video. In my performance tests I came across minor and major GCs. But I didn't know really what those things meant. Thanks for sharing.
@daedalus5070
@daedalus5070 11 ай бұрын
JS2023 is apparently adding some memory management features, would love a follow up on Explicit Resource Management if and when it comes out. Feels like a giant footgun for JS but might be interesting!
@simondev758
@simondev758 11 ай бұрын
Ooh neat, will read about them.
@rj7250a
@rj7250a 11 ай бұрын
That is a quite pointless feature, the point of JS is being high-level, the developer do not need to to worry about lower level details. If you are worring about memory in JS and fighting against the Garbage Collector, you should be using C++ or Rust. I guess that could be useful to optimize legacy codebases, where rewriting everything would be too expensive.
@daedalus5070
@daedalus5070 11 ай бұрын
@@rj7250a It's not as in depth or low level but looks like like it might offer a way to do some basic cleanup which might help with Node and React if used right. See how it turns out...
@AROAH
@AROAH 11 ай бұрын
@@rj7250aConsidering how JS is essentially the default language for a lot of developers, and how JS has such a bad reputation for gobbling up memory, I think the language needs all the help it can get.
@gardian06_85
@gardian06_85 11 ай бұрын
@@rj7250a manual Memory management especially of longer life objects is a scalpel, and should be used thoughtfully. in C++ the expectation is that every programmer "should know" how to use that scalpel, but in reality most of the time the average C++ just writes the destructor, and then only calls delete in the destructor of the holding object, or when an object goes out of scope, which is mostly effective, but can quickly lead to bloat. Java is supposed to be "an easier language" where one of its initial sale points was "you don't need to worry about deleting your objects manually we have garbage collection" when in reality this was targeting those C++ devs that didn't try to dynamically manage memory. Over time many Java devs have leaned to just shrug at memory deallocation as a "Garbage collection will take care of it" which has led to the impression that Jave is inefficient, and for "lazy" developers, and many of the developers that do want to still work in Java, might be frustrated with "you can give it hints, when will it have an impact? Yes, No, Sometimes, Maybe"
@Kaeresh
@Kaeresh 11 ай бұрын
Learning how to properly optimise for v8 (or specific browsers) is definitely something I am _very_ interested in and you seem to have a whole lot more knowledge than you've let on from the video's I've seen of you. Going over some of your own projects and learning what to look for, especially for game-like programs that have a constant frame-update or loop/cycle, is something I would personally love to see you do. Also if you have the time I'm really curious how you would handle a queue/worker like architecture in javascript. It is something I've been tinkering with myself to write POCs for the current project my team is working on.
@Retrofire-47
@Retrofire-47 11 ай бұрын
i was literally *just* going through a tutorial on js GC when you uploaded this - fantastic timing for a fantastic explanation!
@avivkandabi7088
@avivkandabi7088 11 ай бұрын
Hey Simon, I saw that you are working on a Math course, looking forward to it ! Do you think you'll ever make a course for algorithms and data structures? I never found a good online course and your way of explaining things is perfect.
@simondev758
@simondev758 11 ай бұрын
That's a great idea!
@bryku
@bryku 11 ай бұрын
In the past I had a top down rpg style game. This was before requestAnimationFrame was in javascript, so I used a setInterval. The game was having some studders, but I found out that if I just move them off screen instead of deleting them from the entities array it got rid of those stutters. At the time, it sort of puzzled me, because I thought less memory = faster, but as I thought about it, I sort of assumed that the performance saved was because I didn't need recreate all of those objects. I believe your deep dive into GC sort of answered this long forgotten question of mine. Sort of funny how I found solutions around this without really knowing what was happening though. But, this is javascript we are talking about. There can be some really weird behavior sometimes and the only way to know is to test it out... and that is assuming it doesn't change in the next version of v8.
@ThislsYusuf
@ThislsYusuf 11 ай бұрын
Vote for majorgc rename to The Executor ⚰
@jonispatented
@jonispatented 11 ай бұрын
Executioner
@simondev758
@simondev758 11 ай бұрын
The Judge? Named after Dredd :p
@ThislsYusuf
@ThislsYusuf 11 ай бұрын
@@jonispatented 100% right 😁
@ThislsYusuf
@ThislsYusuf 11 ай бұрын
@@simondev758 Not morbid enough I'm afraid haha. Great video Simon!
@LunarLaker
@LunarLaker 3 ай бұрын
the undertaker? or is that taken
@jackwright517
@jackwright517 11 ай бұрын
Really great video! Thanks! Learned a lot about GC
@alaricsnellpym
@alaricsnellpym 11 ай бұрын
I don't know about V8 specifically, but GC systems are often a lot faster at allocating objects than manual memory systems (because the GC can defragment memory by moving objects, then allocation becomes a pointer incrementt), so it's not necessarily true that manual memory management ia faster!
@simondev758
@simondev758 11 ай бұрын
In games, I've had to write many different allocators for different sitautions. You can get really fast allocations under the right conditions by using something like a pool or linear allocator vs the general purpose Doug Lea style allocator.
@BosonCollider
@BosonCollider 10 ай бұрын
@@simondev758 Right, also even using a pool may not perform better in a GCed language if the pool is fragmented in memory, because letting the objects die young can be cheaper than the bookkeeping involved with having old objects point to new ones. Typically for pools to make sense the objects need to be value types allocated together, which is something that javascript mostly can't do unless you reorganize your code from arrays of objects to objects with array fields and basically vectorize everything (which is also what the JIT compiler likes).
@michawhite7613
@michawhite7613 3 ай бұрын
For games, the trick is to ensure you can't save any state between frames within scripts. You can set up a system where all the script's memory is deleted every frame. Then you get the benefits of a bump pointer without the downside of garbage collection.
@meetfilipe_
@meetfilipe_ 21 сағат бұрын
Just to say that your style of explaining things rocks. Thank you for sharing
@anon_y_mousse
@anon_y_mousse 11 ай бұрын
I'd like to see a comparison with regards to memory usage of both Chrome and Firefox in general as well as with rendering something. A simple clone of Asteroids would be a good start and it's easy enough to write and there are pre-written versions in JavaScript everywhere that you could just copy if you were feeling lazy.
@JonatanWallmander
@JonatanWallmander 11 ай бұрын
Not exactly related to GC, but on the note of performance: Another hugely important factor is that in these higher level languages, you can't pack objects tightly in contiguous RAM, the GC metadata/refcounter would be there, possibly pushing alignment. This means less throughput in the CPU, adding to the overall cost. And not being able to align memory and choose smaller datatypes (16-bit float, 32-bit float, 64-bit double just to take one example) means that the CPU can do leaps and bounds more. There are other tricks, not running constructors when you are going to overwrite an array anyway, memory mapped files and so on. Also when making game engines, you have to consider read-ahead cache saturation so the cache misses are kept to a minimum. JS itself provides no such tools (v8 provides some however). After all, games are all about quickly marching through long arrays of floats on the CPU.
@simondev758
@simondev758 11 ай бұрын
That's a good point, although I wonder if TypedArrays gets us most of that? That's what I was alluding to with the "going crazy with TypedArrays" comment near the end.
@JonatanWallmander
@JonatanWallmander 11 ай бұрын
@@simondev758 ah nice, thanks. Didn't know about those. One learns new things every day.
@user-cx6ec2kp6u
@user-cx6ec2kp6u 10 ай бұрын
Came from the primeagen, saw my ad, did my part. Great vid👍
@planetmall2
@planetmall2 11 ай бұрын
This is so next level. Thank you for this video!
@lordxan1
@lordxan1 11 ай бұрын
Nice video I hope to see a memory comparison in the future
@lachlanburns4382
@lachlanburns4382 11 ай бұрын
Great video, very informative, cheers!
@fibulawars
@fibulawars 11 ай бұрын
Thank you for the video! Always interesting non surface level topics.
@Skeffles
@Skeffles 9 ай бұрын
Really interesting video!
@flygonfiasco9751
@flygonfiasco9751 11 ай бұрын
Great video, I would love to see how much functional programming (with immutable objects/arrays) triggers garbage collection vs mutable imperative code. How much more cpu cost (if any) are we eating when we code functionally
@SeanJMay
@SeanJMay 10 ай бұрын
I don't know that you would need to freeze the objects, or recursively freeze the given data structures. Treating them as read-only by convention of function would be sufficient. One immediate caveat: the built-in `map` `filter` `fnd` `reduce` etc are *slow*. They have to check for sparseness of arrays, weed out non-numeric keys, dynamically bind to `this`, create a shallow copy of `this` in case a function mutates values of indices on `this` during iteration, et cetera. Handwritten versions of the same thing (that expect non-sparse, numerically-indexed arrays with no mutation, etc) can be much faster. It would also be neat to see the time / memory costs of composed partial applications of functions. I can tell you first-hand that it's more than sufficient for high-performance interactive experiences. Making things like interactive SVG graphs, in React, with heavy client-side data analysis from raw data, and separate linear algebra for correct positioning, and all of the line segment highlighting, collision detection for hover states, modal popups to render data points, etc, without significant impact on laptops in the past ~8 years. On the main thread, no less. Not good enough to support running Quake 3 in FP, I’m sure, but surprisingly good if the libraries used are tight in performance, and you keep all logic segregated from anything that remotely smells like DOM access. And this was written... 5 years ago... geez, I’m old.
@gownerjones1450
@gownerjones1450 11 ай бұрын
I am become majorgc, the bringer of death.
@codahighland
@codahighland 11 ай бұрын
In my JS game engine, I saved a RIDICULOUS amount of time by reusing objects whenever possible instead of making new ones. I even went so far as to have internal worker functions use a single permanent object at module scope for temporary values. As a result, it was able to keep up with 5000 interacting and colliding objects on a 2013-era laptop while maintaining 60fps. Irritatingly, performance has gotten worse since then in Safari because of weirdness in how Apple rebuilt the canvas API there. I still haven't figured out how to work around that.
@SimonBuchanNz
@SimonBuchanNz 11 ай бұрын
You need to be *very* careful doing this. Not only is it quite easy to leak the shared objects and have a "randomly changing" entity, but if you end up putting different contents in the same object you can crater your performance. Keep in mind very short lived objects are very cheap, they're not the case you need to optimize.
@codahighland
@codahighland 11 ай бұрын
@@SimonBuchanNz Oh, believe me, I know. Like I said: internal functions only. And I profiled it -- though I don't know if it would still have as much of an impact today.
10 ай бұрын
Thank you for sharing your experience, is there any kind of example we can examine and learn from it by any chance ?
@zeekcom12
@zeekcom12 11 ай бұрын
You have a buttery smooth voice like bob from bob's burgers, love the vid man
@melkileo
@melkileo 11 ай бұрын
Very interresting video, never disappointed !
@chieeyeoh6204
@chieeyeoh6204 11 ай бұрын
Even though I don't understand most of points, but I think the way you presented it is very interesting
@abdelrahman5094
@abdelrahman5094 11 ай бұрын
I need another 10 hours of content to understand this single video
@raylopez99
@raylopez99 11 ай бұрын
I thought it was pretty straight forward and I'm hardly a guru, just hobby code. What was interesting was @7:02 where it was said that 26 ms of time for the GC, a skipped frame, was "unacceptable" to game developers! Wow, they have demanding criteria for unacceptable. 26/1000 = 2.6% of a second, hardly a blink of an eye. Are players that competitive that 26 ms lag will make them rage quit a game? I guess so. I recall reading C# was used to build an expensive trading system at some stock exchange, I think it was London Stock Exchange, and they scrapped it when they found it was a few milliseconds slower than C++, which HFT did not like.
@simondev758
@simondev758 11 ай бұрын
Yeah, I've been a gamedev since the early 2000's, specifically specializing in optimization. I've spent time shaving fractions of a millisecond off a function, reordering data or statements to make them cache/branch predictor friendly, etc. 26ms is huge heh, at least it is in that world
@SETHthegodofchaos
@SETHthegodofchaos 11 ай бұрын
​​​@@raylopez99 if you expect to simulate your game objects 30 times a second (or more) then you only have 33ms for each update tick for a stable tickrate. You need to update all game objects that need updating, check for collisons, handle those if they happened, and in online games also sent out the state changes to all clients as well as run any netcode shenanigans to save on bandwidth and make the game feel smooth and as fair as possible for the clients even tho each player has different latency and thus differ in game state on their end. And especially if you have a lot of servers running then it makes sense to want to reduce their cost as it will directly have an impact on profits.
@raylopez99
@raylopez99 11 ай бұрын
@@SETHthegodofchaos Wow that's a lot of things to do in a short amount of time...I always suspected games compensate for slow connections (the same thing happens in online chess blitz matches which I play, with time added for a slow connection) but your post was the first time I've read about it.
@HyuLilium
@HyuLilium 10 ай бұрын
​@@simondev758 is this the reason games take decades even with huge bugets? Why can't game dev be done inefficiently then optimizing after measuring, once the whole game is complete?
@etunimenisukunimeni1302
@etunimenisukunimeni1302 11 ай бұрын
I could watch this kind carefree exploratory and super informal testing of... stuff all day. "Well this isn't a very realistic test, I'll just cough up a toy game simulator to see what happens." It might not exhibit mad skillz, but impressive that you wanted to go through the trouble anyway. Cool 😄
@primitivedev.
@primitivedev. 11 ай бұрын
Greetings, could you talk about creating optimized projects with three js specifically?
@4evrplan
@4evrplan 3 ай бұрын
I would love to see a comparison of this GC test to one using entirely static memory!
@iatheman
@iatheman 11 ай бұрын
Such an impressive work going to such a crazy programming language.
@s1l3nttt
@s1l3nttt 11 ай бұрын
Bro 💀💀💀, infant mortality, no way
@rogo7330
@rogo7330 11 ай бұрын
Shortlived objects can be just stack variables. They don't needed to be explicitly cleaned up even in C. The problem with dynamic-memory languages is that they use pointers to pointers to pointers to (finally) data, instead of directly asking how much do you need and for how long in a first place. Sometimes people just write OOP-bullshit that creates a lot defragmented objects you don't know about instead of just allocating what you need in this context and give that chunk of memory to some functions that will read it, change it or copy.
@zactron1997
@zactron1997 11 ай бұрын
The control in allocation strategy is where languages like Rust and (moreso) Zig are heading. In Zig's case, even 3rd party code must be handed an explicit allocator, allowing multiple allocation strategies within a single combined program. Pretty great control, but I prefer Rust's abstractions personally.
@diadetediotedio6918
@diadetediotedio6918 11 ай бұрын
me too
@raylopez99
@raylopez99 11 ай бұрын
Rust doesn't have GC, as you know, but it does have lifetime annotations, which I don't like since I don't really understand them at the practical level aside from parallel processing, but I do see they are built into a lot of library functions.
@diadetediotedio6918
@diadetediotedio6918 11 ай бұрын
@@raylopez99 The lifetime annotations in Rust are logical pointers to the compiler, they don't go into the runtime environment like a GC. Rust is not fundamentally different from C in how it allocates and frees memory, the only difference is that you don't have to explicitly worry about it (most of the time). Added to things like ref-counting that eliminate the cases where lifetimes cannot be used, it manages to cover the needs of software development.
@zactron1997
@zactron1997 11 ай бұрын
@@raylopez99 The lifetime annotations allow a sort-of compile time garbage collection. In Rust, every variable and memory allocation has a definite beginning and end, aka a lifetime. For 99% of what you write in Rust, the lifetime is trivial to infer from context. For example, I declare a float inside an if statement, and never reference it again outside that if statement. In this case, the lifetime begins at the start of the if statement's scope, and ends when the scope ends. For pointers and references, lifetimes sometimes need to be explicit because it's not trivial. For example, you may create a structure and pass it around from function to function, in and out of all sorts of scopes. Making a lifetime explicit is done through a lifetime annotation, which just names the scope of a variable for the compiler.
@lawrencedoliveiro9104
@lawrencedoliveiro9104 11 ай бұрын
Why not implement it the way Perl and Python both do, and that is to use reference-counting as a first resort, and only fall back to garbage collection in situations where that fails (i.e. reference loops). That would seem to give you the best combination of performance and flexibility.
@lovalmidas
@lovalmidas 10 ай бұрын
In a way, it might not just be that custom allocators / reuse patterns improve performance by reducing GC time, but also by reducing allocation time. It is like a reverse GC where instead of searching objects to delist from active memory, you search memory of desired size to reserve that object you need. Not sure if you can monitor pure allocation time using the chrome tool though.
@motbus3
@motbus3 11 ай бұрын
Cool. I've done similar comparisons in java once when they launched the "new" GC.never thought how it worked on JavaScript I am curious how do you override memory allocation at global level in c++. Do you implement your own allocation method or do you override new/malloc?
@TheJeremyKentBGross
@TheJeremyKentBGross Ай бұрын
You can override new and delete in C++, globally or on a per class basis, and/or make your own malloc/free wrappers/stand ins. It's handy to make a template class that overrides new/delete for a parameter class, thst has one pre allocated array as a static member for use as a pool or bucket/slot list. Instances of the class are the same size, so this array doesn't fragment. Just use an unused slot for the allocation. You inherit from the template with itself as a parameter MyClass: public Pool{...} Globally there's a lot you can do, but one really efficient one is to basically have one array again and just allocate iteratively along/from it. Whenever you go into a new global game state (say leave one level and go to another) you can just reset back to the start, or a predetermined push/pop pointer into to allocate sequentially from again. You still should run destructors to free video memory assets and such, but having a global allocator that can just allocate sequentially for (relatively) permanent stuff for the time being, and never go back except when everything is reset, can be great for a lot of cases. Doing these things, plus reserve for stl vectors, is some of the best performance optimizations I've ever gotten out of C++, save avoiding dynamic memory in general, which these strategies sort of do. The normal memory allocation algorithm is super slow (from a game pov), not to mention usually thread safe which also implies locking overhead. It's best if that never happens but once at startup. So often you allocate ALL system memory at startup and allocate it yourself in one of the mentioned or a few other ways. Especially on console. Or at least it was ao when I did such work in the 2000s.
@codahighland
@codahighland 6 ай бұрын
Somehow I managed to forget I watched this video even after watching it again. I came here to comment and discovered a comment by myself!
@LeeSmith-cf1vo
@LeeSmith-cf1vo 11 ай бұрын
I got an interesting takeaway from this - complex objects are more GC costly than simple ones. This makes me think that if we have a situation where we have a complex object that we need to keep around for later but we don't need to access it for a while, it would be worthwhile to serialise it into something like a TypedArray, discard the original and then reverse later when we need it, as then there would be only a single pointer for the GC to consider, despite a similar memory footprint. I can't imagine there any many circumstances where this approach is practical, but if it is, it could be worth exploring.
@brandonsayring
@brandonsayring 11 ай бұрын
Very interesting deep dive into v8's gc. I love that they named the garbage collector after a character from The Wombles. Also, I noticed recently in some of your github repos that you have added a few math utility functions which are already provided in the three's MathUtils object (just in case you werent aware of that object). Cheers.
@simondev758
@simondev758 11 ай бұрын
Had no idea, sometimes I just out and just implement things instead of checking around, especially short little functions like that heh
@ajflink
@ajflink 10 ай бұрын
Python has a garbage collector; however, I rarely see code where it is utilized manually. In most cases, Python has a very good automatic garbage collection from my experience. However, I tend to heavily utilize the array module, nested lists and tuples, list comprehension, del keyword on objects that will not be used again in the code immediately after the last instance of where it can be used, use xrange instead of range whenever possible when in Python 2.7.18, and have sets used when going through large iterations to skip redundant conditional checks. Funnily, many of the things are listed are frowned upon in the Python community placing readability on podium and throwing efficiency out the window. I also use modulus string for "string concatenation". It is apparently not as good as f-string; however, it is available in both Python 2 and 3. Yes, people still use Python 2. After the initial release of Python 3.0, can you blame people for still using Python 2?
@the_primal_instinct
@the_primal_instinct 11 ай бұрын
Grim Reaper would be a good name for MajorGC because it comes for old objects
@andythebritton
@andythebritton 11 ай бұрын
Orinoco? Like the Womble? Love it.
@johnpekkala6941
@johnpekkala6941 11 ай бұрын
Unreal Engine uses C++ but it too have some form of GC but its not built into the language itself but handled by the game engine and I wonder if that makes it a bit more optimized. In any case you never need to deal with manual memory management in Unreal Engine C++ either and I have seen there is also a settings tab in UE for the garbage collection system. In Unity i dont know if the GC is controlled by the C# system or Unity itself but i bet it is the former as it after all uses C# wich is by definition a GC language. I saw someone testing GC performance in Unity once and it took away some substantial performance what I could see when he pushed it. The most devastating thing would be if this occured in say a boss fight and the game freezes at a critical moment when you are about to land a critical hit because the GC goes in right then and so you die cause u miss the hit cause the game lags/skips while the GC is working. The big issue in geenral is that with GC the programmer have NO control at all over when it goes in. GC would be the perfect thing however if you could tell it to "WAIT until i have done this". Like its normally all automattic but there was some command to tell it to wait for critical stuff to finish first, like a semi manual option. This we dont have in any GC language however.
@cold_fruit
@cold_fruit 3 ай бұрын
Call me a troll but as soon as I saw we were working on the level of milliseconds my answer to the question posed in the title of the video is emphatically "yes, yes it is". Although it's relative - the cost of everything in JS is on the same order (of ms) so in terms of JS code, worrying about the GC is a micro-optimisation strategy. But running that program on a computer with a GHz-order clock speed we should all be astonished that the latency is on the order of milliseconds. I get that there's a browser stack and JIT compiler and all the other stuff getting in the way, but it's worth reminding ourselves (as programmers) just how much the hardware we're using is capable of from time to time, so that we don't become complacent in expecting huge latencies from the platform layer.
@FinlayDaG33k
@FinlayDaG33k 11 ай бұрын
Just call MinorGC the "Infant Annihilator"... Then hope you don't get sued by the metal band of the same name.
@simondev758
@simondev758 11 ай бұрын
lol
@stevenlischer
@stevenlischer 11 ай бұрын
What machine are you running this on? Sorry if I missed in video. Would like to try this on an older chromebook and see if there's a significant difference
@simondev758
@simondev758 11 ай бұрын
i7-4790k from 2014.
@PranayKotapi
@PranayKotapi 11 ай бұрын
Just here to say you're amazing
@BertVerhelst
@BertVerhelst 11 ай бұрын
I always wondered if there is a way to compile JavaScript to wasm code with an ahead of time compiler and compare that performance to the jit compiler interpreting the same JavaScript code.
@simondev758
@simondev758 11 ай бұрын
No idea, that would be kinda interesting, although the generated code would need some sort of leg up on js to generate better code than what the jit compiler is already doing.
@syntaxerorr
@syntaxerorr 5 ай бұрын
I've used this many times and never knew about the wasd keys.
@kajacx
@kajacx 10 ай бұрын
You can still (kind of) use manual memory allocation and reclamation in GC languages. Let's say you have a vector object with z, y, and z fields. Instead of creating a new object every time you need a new vector, you can store old unused vectors in a global list and take an old vector instead. This gives you all the "horrors" of manual memory management from C++: you have to know when is the last instance where you use a vector and "free" it by putting it in the "pool" of unused vector. But it avoids memory allocation when creating new vectors. This of course isn't complete replacement for manual memory management, but can work and has some of the same upsides and downsides of manual memory management in C++. Or you can just use Rust and compile it to WASM.
@CrippleX89
@CrippleX89 11 ай бұрын
Personally, I very much prefer ARC, a very interesting concept that you don’t really see all that much (sadly). imho it’s best of both worlds: performant (in theory, when done right), way less overhead than GC and much more controllable. The only real “downside” is that the language would need to define whether a reference to an object is strong or weak so there’s a bit of a learning curve for developers that aren’t familiar with that concept. But then again, it’s good to know what those are anyway!
@simondev758
@simondev758 11 ай бұрын
Really interesting, haven't heard of that but I'm going to go read up.
@greggoog7559
@greggoog7559 11 ай бұрын
It's used extensively in Apple's stuff (Objective-C & Swift).
@vitalyl1327
@vitalyl1327 10 ай бұрын
there's a lot of problems with ARC too - firstly, unpredictable run time, if it's reclaiming a large structure it may not finish in time. Secondly, you're losing the cache-friendly advantages of a compactifying multi-gen GC. Also, cycles are a bit of an issue too. So, it's not really useful for real-time, and have a worse amortised performance as multi-gen GCs in throughput-oriented loads.
@vitalyl1327
@vitalyl1327 10 ай бұрын
@@greggoog7559 apple, schmepple, it's much older than that, it's in Python, it's in Mathematica, and many other older languages.
@giantisopod
@giantisopod 4 ай бұрын
It's worth noting that reference counting is only fast as long as your reference counter is single-threaded (i.e. objects are not shared across threads). Otherwise you need atomic instructions which stall the CPU on every release. This adds up if you have lots of objects. Periodic garbage collection could - at least in theory - be faster in that case.
@phoenix-tt
@phoenix-tt 11 ай бұрын
Very impressive! I would also love to see how JavaScriptCore and SpiderMonkey handle garbage collection, is it similar to V8? I know Firefox has the same tool you were using, and Safari mostly likely has it as well.
@henriquecardoso45
@henriquecardoso45 7 ай бұрын
Next video coming when?
@javifontalva7752
@javifontalva7752 8 ай бұрын
When will the Math be available?
@simondev758
@simondev758 8 ай бұрын
I'm trying to finish up the last section this week actually.
@rockyf2p
@rockyf2p 11 ай бұрын
Cool video
@akinaguda
@akinaguda 11 ай бұрын
Test writing game business logic in a language that compiles to Web Assembly vs JavaScript
@tsunekakou1275
@tsunekakou1275 11 ай бұрын
didn't think i am going to get flashbanged 10 second into a video.
@Exmantika
@Exmantika 10 ай бұрын
Great video! I laughed at seanbean. 😂
@NotGarbageLoops
@NotGarbageLoops 10 ай бұрын
In my experience, if JS garbage collection is the bottleneck, you're doing something very, very wrong. Usually a bug in game code. My disclaimer is that I exclusively develop for Chrome and NW.js - Firefox is a whole different annoyance that makes you feel powerless.
@dditions
@dditions 11 ай бұрын
Very neat and much better than having ChatGPT trying to explain these intricacies to me :') Thank you Simon, keep it up! :D
@roberthickman4092
@roberthickman4092 10 ай бұрын
Test firefox please. I've been seeing weird behaviour in it in one of my programs that I have no idea what's causing. It's periodically dropping a bunch of frames seemingly randomly, and it isn't GC, at least not obviously. The profiler is just showing a 'wakeup' event then the browser goes to sleep for the whole frame.
@syn8485
@syn8485 3 ай бұрын
I'm a bit confused, the video title talks about JavaScript's GC, but the content only mentions v8. That's very much not the same thing.
@kvbc5425
@kvbc5425 11 ай бұрын
yes 🙂
@charlesbenca5357
@charlesbenca5357 11 ай бұрын
The other day i implemented in javascript some very heavy math computation. I used iterators instead of memory wasting arrays. Then i wanted it faster so i reimplemented it in c++ and it was the same speed as javascript. Mathematicians should drop python and go with javascript
@simondev758
@simondev758 11 ай бұрын
Access to SIMD really makes the difference in c++
10 ай бұрын
As iterators did you use objects with for loops or something else can you please share little bit information?
@isodoubIet
@isodoubIet 11 ай бұрын
Probably shouldn't use C++ as an example of a language where you have to "explicitly" free memory. C++ solved memory allocation deterministically, at compile time, without gc, since the 80s.
@OREYG
@OREYG 9 күн бұрын
This biggest cost of GC is that it rids you of an ability to reason about your memory layout, only for a convenience of not having to deal with weak pointers.
@DeveloVooshGWeb
@DeveloVooshGWeb 10 ай бұрын
The question is not "Is javascript's garbage collection bad?" The question is "is javascript's garbage collection garbage?"
@Gabirell
@Gabirell 6 ай бұрын
🤯*😂
@hanifkhan2821
@hanifkhan2821 7 ай бұрын
keep posting more video games tutorial using javascript.
@u9vata
@u9vata 11 ай бұрын
Its not GC that is the biggest issue, but everything being reference / pointer instead of direct inlined storage...
@mariocamspam72
@mariocamspam72 11 ай бұрын
What? There are many situations in which you can't just shove data on the stack. The heap exists for a good reason.
@u9vata
@u9vata 11 ай бұрын
@@mariocamspam72 placing everything inlined does not necessitate its on the stack - you can just as well place them in a heap-allocated array or a vector - just its not pointers and the (p)OOP style design of references, virtual functions and all that, but literally the objects are near each other. And this is not even data oriented design yet, just regular easy-peasy locality. Only after this one can really wonder about "okay now what part of that data is accessed the same time" so this is very baseline code quality - not even an optimization, but a default to not pessimize performance... Also with RAII and move/copy you can just avoid naked pointers and references in most cases even without any "smart pointer" kind of thing... Very gentle and easy style with good perf comes out of it.
@raylopez99
@raylopez99 11 ай бұрын
@@u9vata You sound like the perfect candidate...for Rust.
@u9vata
@u9vata 11 ай бұрын
@@raylopez99 Really not a rust fan, because of the borrow checker, not much benefits and still slow compile speed. Rust really does not give much at all for safety when cpp is done well and is worse for productivity. I am happy though that Linux kernel has no C++ and would maybe do rust for huge teams, but where I know the team I prefer C++ for greenfield projects - only bad in legacy sometimes. But I am waiting for Jai which I have good feelings about and also think about creating my own language because I have a resource management idea that is much more simpler than the borrow checker and "nearly as safe". The good things about rust is basically its enums and match statement, but otherwise not really interested after I tried it for a while. For me the biggest issue is that it was pretty slow to write the same solution when it comes to programmer productivity and also very slightly was slower. I usually use C++ for hiperf though like data structures, or I even have my own sort algs that outperform libs and such so for my use case rust is not giving much - yet I am sure where safety counts more then both productivity and speed its better so there is place for it. Interestingly I see more interest in rust from web devs direction and somewhat from the systems development like OS dev, but not really seeing interest for rust in 3D / cad / games / hiperf where the productivity plus speed outweights safety benefits a lot. And again not really that big benefit when doing modern cpp... For this area I bet Jai / Zig / or maybe even my own imagined lang fare better because more focus on productivity is key and more focus on lets say compilation speed - which is real issue also in rust not just cpp...
@whtiequillBj
@whtiequillBj 11 ай бұрын
Firefox is mostly written in Rust I'm pretty sure
@Zaphispo
@Zaphispo 10 ай бұрын
Any reason you're never testing JavascriptCore or SpiderMonkey ?
@ristekostadinov2820
@ristekostadinov2820 11 ай бұрын
When are you planning on making WebGPU video
@alleycatsphinx
@alleycatsphinx 11 ай бұрын
Is "static" the hint you're looking for? ;D
@muhamedkarajic
@muhamedkarajic 10 ай бұрын
"How is the performance on Firefox? Great question, no idea, havent test those."
@ichimid
@ichimid 5 ай бұрын
top
@planktonfun1
@planktonfun1 11 ай бұрын
same as c++ you have to explicitly free it
@bothieGMX
@bothieGMX 3 ай бұрын
So what is the main takeaway? For me it's the same takeaway of any GC related video/talk/text I see/hear/read: Don't use GC. You may use a language that uses GC but then you have to implement your own memory management on top of it (an object pool is nothing short of a custom memory allocator). So, basically, I still fail to see the point in using GC at all. GC is more cpu efficient -> debunked GC is more memory efficient -> debunked GC has no memory leaks -> debunked GC causes lag spikes and other issues -> confirmed over and over again
@simondev758
@simondev758 3 ай бұрын
The takeaway is whatever you want it to be. If you have ingrained and immoveable opinions, then you'll take away something that supports them. Or if some data or finding in there surprised you, maybe it changed your opinion on things. I fiddled around and tested things, and showed the result, that's all.
@bothieGMX
@bothieGMX 3 ай бұрын
@@simondev758 Just in case you felt attacked by me, that was not my goal, sorry for that.Some years back, I had GC issues in Minecraft as well, but I was limited to fiddling around with the GC settings, the result was some extreme settings for G1GC which made the lag spikes almost go away. So, I know what fiddling and testing around looks like and I appreciate the work you did.
@0dWHOHWb0
@0dWHOHWb0 3 ай бұрын
You really shouldn't be mallocing in C++, and memory management shouldn't be explicit if you can help it -- you should prefer RAII Perhaps you meant to say C
@VictorMistral
@VictorMistral 11 ай бұрын
Though in C++ you should let RAII deal with memory lifetime. malloc, and free are code stink, and really bad. new and delete should not be used, unless you are an expert. what you want in unique_ptr, and shared_ptr...
@simondev758
@simondev758 11 ай бұрын
I've generally been responsible for optimization on a few games. When performance is important, you're managing the memory yourself, not via raii, smart pointers, etc. Those are great, although they have their own footguns and drawbacks.
@VictorMistral
@VictorMistral 11 ай бұрын
@@simondev758 Thanks for the reply. (No need the read the rest...) Sure if you really need the get the max performance, reusing memory, and controlling when allocation and free is done is required. Though OS mem allocators are usually pretty good at cheap free and reallocate on the same size nowadays... They are not perfect. PMR was added to help with that. But at this point, if you are considering thus things, I can say that that you are working at a "expert" level, so new/delete (and their overload, in-place, and array variant) are tools you should use. However, for most dev, the rule of thumb is use RAII, so that there is no mem leak, as something more important then perf. Optimize if you have to, where it makes sense. Most of the time, it's not the memory alloc that makes something slow or fast, but the architecture and algos. (if are surprising costly, especially if mispredicted, and doing something in O(nlogn) when you could do it in O(logn) will have more impact then allocs. (and don't forget that O notation is not that good, as it's only true for infinite N, so consider the size of the N when selecting the right algo) ... (and that is why doing things in other language then "low-level language" can result in the same or better perf...)
@colonthree
@colonthree 11 ай бұрын
ECS + Object pooling...? ;w;
@throwaway3227
@throwaway3227 11 ай бұрын
The majorgc should be called Covid mortality.
@victorvandermilte5857
@victorvandermilte5857 11 ай бұрын
You sound like the Bob's Burgers guy
@nicksavoon
@nicksavoon 11 ай бұрын
Yeah, sometimes put the math at the GPU rather javascript.
@simondev758
@simondev758 11 ай бұрын
Absolutely
@kisaragi-hiu
@kisaragi-hiu 11 ай бұрын
Can you at least mention in the description that this is specific to V8? You're presenting it as if V8 = JavaScript.
@nexovec
@nexovec 11 ай бұрын
Why people think js is horrible is more about the collective damage of how it changes the way you program when you don't think about memory at all, how you have less control over types, how stuff is bigger in memory than it needs to be and how the program behavior is unpredictable.
@Brad_Script
@Brad_Script 6 ай бұрын
I think the problem with javascript is constantly creating objects
@FlanGrande
@FlanGrande 10 ай бұрын
I like the mutilator
@edblarney9456
@edblarney9456 11 ай бұрын
Javascript is not V8 there are other implementations
@platin2148
@platin2148 11 ай бұрын
GC is search so as long as you are fine with the performance hit that can or cannot create in certain cases it's fine. Meanwhile the Interpreted stuff on anything will always be slower than a direct translation. And JS is notoriously known for hundreds of packages + a ton of pointless abstractions and a mega problem in terms of types. So if you want fast and efficient simply choose a other language.
@redgood5879
@redgood5879 7 ай бұрын
please make new awesome videos
@0xpatrakar
@0xpatrakar 11 ай бұрын
Ok, but who names functions like Dosomethingstupid and not do_something_stupid or doSomethingStupid? Or was it irony.
@raylopez99
@raylopez99 11 ай бұрын
He's not a rust_developer_maybe?
@0xpatrakar
@0xpatrakar 11 ай бұрын
@@raylopez99 where did rust come from 🤕
@Achilles
@Achilles 7 ай бұрын
why not just use super morbid terms for garbage collection 🤣🤣
@ruben-xt8hm
@ruben-xt8hm 11 ай бұрын
you sound like bob's burgers
Spatial Hash Grids & Tales from Game Development
19:08
SimonDev
Рет қаралды 110 М.
Performance of JavaScript Garbage Collection | Prime Reacts
26:46
ThePrimeTime
Рет қаралды 68 М.
Don’t take steroids ! 🙏🙏
00:16
Tibo InShape
Рет қаралды 39 МЛН
How Big Budget AAA Games Render Bloom
13:23
SimonDev
Рет қаралды 104 М.
An In-Depth look at Lerp, Smoothstep, and Shaping Functions
8:39
The ONE Texture Every Game NEEDS
9:00
SimonDev
Рет қаралды 246 М.
Girl camera photo Editing 3d with adobe Photoshop /9/33/Am
0:43
Amir TECh
Рет қаралды 251 М.
На iPhone можно фоткать даже ночью😳
0:30
GStore Mobile
Рет қаралды 1,4 МЛН
iPhone green Line Issue #iphone #greenlineissue #greenline #trending
0:10
Rk Electronics Servicing Center
Рет қаралды 4,2 МЛН
How much charging is in your phone right now? 📱➡️ 🔋VS 🪫
0:11
🤖Вернулись в ПРОШЛОЕ🤪
0:28
Demin's Lounge
Рет қаралды 60 М.