The Importance of Scalable Code // Code Review

  Рет қаралды 141,888

The Cherno

The Cherno

Күн бұрын

Пікірлер: 247
@TheCherno
@TheCherno Жыл бұрын
Thanks for watching! ❤ To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/TheCherno. The first 200 of you will get 20% off Brilliant’s annual premium subscription!
@goodgoyim9459
@goodgoyim9459 Жыл бұрын
what are your thoughts on vim? possible to develop video games on it like with vstudio?
@amoldhamale3202
@amoldhamale3202 Жыл бұрын
@@goodgoyim9459 You didn't ask me so probably shouldn't be answering. Vim's a great tool but not for large projects in my opinion. You don't necessarily need an IDE like Visual studio, a code editor like vscode would be just fine. However on vim, you will miss some great extensions and intellisense features of vscode. I generally use vim for quick refactoring, editing and writing small programs. There's nothing faster than vim when it comes to refactoring and editing if you know the right set of commands.
@eluddite889
@eluddite889 Жыл бұрын
I hope you're not making fun of my Chess app. There's a limited number of moves so it makes sense to use multiple if statements.
@the_fl3dd0x
@the_fl3dd0x Жыл бұрын
I would absolutely like to see you actually implement the things you talk about.
@hourglass2836
@hourglass2836 Жыл бұрын
this
@ultimatesoup
@ultimatesoup Жыл бұрын
The best way to do this is to have a common base type for all objects with no virtual. You will get different behavior by adding different components to different objects. So maybe an object has a camera component, a sound component and a render able component. The object will just iterate through those and call the update function on each of those components. This way every thing can be in one object manager and you don't have all those repeated containers
@nevemlaci2486
@nevemlaci2486 3 ай бұрын
​@@ultimatesoup That isn't what any half-competent game does tho
@bruno-bnvm
@bruno-bnvm 6 күн бұрын
Well is not black magic. He makes completely logical arguments.
@CatzHoek
@CatzHoek Жыл бұрын
Maybe not always but it would be cool to see the actual code you would produce for certain things once in a while.
@Squirrelies1
@Squirrelies1 Жыл бұрын
As someone who is proficient at C# but fairly new to C and C++, I find your content helpful. I don't fall into the pitfalls of this video per-se but your content really helps me coming from another background and space.
@ale-lp
@ale-lp Жыл бұрын
The world needs more data oriented examples please. I'm still trying to wrap my head around it
@Mini_CS
@Mini_CS Жыл бұрын
I have a video on my channel that might help (if you are still having this problem. I know its been a month)
@ale-lp
@ale-lp Жыл бұрын
@@Mini_CS Yup, I'm still struggling with this concept since I don't have enough time to put into learning this kind of stuff, my day job is just boring. Will take a look for sure, thanks!
@MrHaggyy
@MrHaggyy Жыл бұрын
Well the basic idea is simple. How much data do i have? How many functions do i have? And how does the controlflow of my program look like when i iterate over every datapoint and decide which function to apply or iterate over every function and check to which datapoint it applied. The simpler the structure the better.
@stephenelliott7071
@stephenelliott7071 Жыл бұрын
An Entity Component version would be very helpful, as would performance profiling with cache misses vs the current code IMO.
@Dr-Zed
@Dr-Zed Жыл бұрын
I love combining random adjectives with the word "code" - scalable code - clean code - sad code - trashy code - delicate code - hesitant code - cute code - sassy code - perfect code - strict code - expensive code - shiny code - resilient code - disgusting code - repulsive code
@lazergenix
@lazergenix Жыл бұрын
Yeah, I see what you're saying, but honestly super-diffraction hyper euclidian code would really be what you would need to strive for in any code project. If you do not achieve sonic kinetisis, then you won't be able to even get to the stage of late giga-photosynthesis; something that is rarely even mentioned nowadays. The tips I ALWAYS use in any of my code projects, is to always make sure to inject the right amount of hydro-classes to make sure my structs always retain their polymorphism, and to NEVER intoduce morpho-incapitance, as it will always lead to rapid decay of the code fibers. But thats just me.
@christopheriman4921
@christopheriman4921 Жыл бұрын
@@lazergenix Hmm yes, this definitely makes perfect sense. Hydro-classes probably would have to do with when you get water in your computer.
@rafa_br34
@rafa_br34 Жыл бұрын
It's missing the "- resilient code"
@Dr-Zed
@Dr-Zed Жыл бұрын
​@@rafa_br34 updated the list
@peezieforestem5078
@peezieforestem5078 Жыл бұрын
adjectives are all well and good, but what about "zero code"? I heard it's the next big thing.
@BulletproofOutlaws
@BulletproofOutlaws Жыл бұрын
Hey Cherno! Two time-saving ideas for you for rewriting code in these vids: 1) You could just use simplistic pseudo-code, skip a bunch of syntax and just rough out the overall idea…then we still have to do some problem solving to turn it into usable code, but it would be more clear than trying to verbalize what you’d do (drawings like you sometimes do would work too!) 2) ChatGPT has been a big help to me for learning, maybe you can have it spit out or refactor code for you, getting an end result close enough to what you would do to explain things like “make these objects into an ECS” I find refactoring vids one of the most useful resources because we all make a lot of the same mistakes at first and watching someone with experience step through refactoring as they explain their decisions is a huge help to get from beginner to intermediate/advanced
@РайанКупер-э4о
@РайанКупер-э4о Жыл бұрын
I would love to see this code actually modified using your recommendations.
@HenryLoenwind
@HenryLoenwind Жыл бұрын
There's also a halfway way of doing this. You can put all the common stuff into a base class (or even struct) and then include an untyped pointer to the specific class for that object (along with a type marker so you know what to cast it to) in it. That way, your common code works for all game objects, and they are tightly packed in memory. When including a "dead" flag, you can even use a dumb array for game objects that are not extremely short-lived. Including a deletion counter and a garbage collection routine to pack the array when it had too many deletions also makes sense. I like to write my own collection classes that know what kind of data they hold. This also allows me to do such trickery lie splitting the stored objects into multiple lists or filtering the objects by type (without looping over all of them because the Collection class can cheat with array slices or sub-lists by object type it keeps in sync with the main list). While the code inside that collection isn't really that different from what would be outside when using generic lists, being able to call "give_me_all_movable_and_collideable_objects_that_collide_with(player)" makes the high-level code so much clearer to read and makes it easier to change the way the data is stored easier as it's all in one place.
@Treborbobuk
@Treborbobuk Жыл бұрын
To answer the question about whether it's worth you re-writing stuff on camera, I think that could BE the video - where I work the devs often make code change suggestions as part of the code review (even though I tend to discourage them doing that in the cases where it means a more senior dev ends up writing the code for a junior) It would be great to see what you would do vs what was done to compare and contrast. Love your content and I really enjoy these code reviews!
@Domix-nh8ws
@Domix-nh8ws Жыл бұрын
Please rewrite it with an ECS, or something similar it would be amazing to see the comparison.
@omarmagdy1075
@omarmagdy1075 Жыл бұрын
This is hands down one of the most educational series for programming I have seen. I have acquired some many good tips out of this series and it affected my day to day coding to the better. Keep up the amazing work.
@fyvefouroh
@fyvefouroh Жыл бұрын
You should use a tool that measures cache hits and misses on this project for fun. I think it would be interesting to see
@amoldhamale3202
@amoldhamale3202 Жыл бұрын
I agree
@urugulu1656
@urugulu1656 Жыл бұрын
no the birds do not need inheritance. just add a bitfield for the colors instead . this would also enable multi colored birds which would likely be a fun game mechanic. and for the thing with the numbers being added or subtracted from the score just put these in an array that can be indexed by the bitfield value being casted to an integer.. (but maybe i am just too deep into the microcontroller / c99 way of thinking)
@xeridea
@xeridea Жыл бұрын
I was thinking same thing. All birds the same class, but just reference an array based on bird type for values.
@legitjimmyjaylight8409
@legitjimmyjaylight8409 Жыл бұрын
Or use the strategy pattern, or even just an entity component system.
@soniablanche5672
@soniablanche5672 Жыл бұрын
or just put the score as a property of bird
@yiranmushroom
@yiranmushroom 6 ай бұрын
You should use inheritance here if you want to do it in a more C++ way.
@nevemlaci2486
@nevemlaci2486 3 ай бұрын
​@@yiranmushroomdoing it with inheritance is very inefficient tho, loads of cache misses 🤷‍♂️
@APaleDot
@APaleDot Жыл бұрын
> Is zero an even number? The answer is a definitive "yes"! It satisfies every property that even numbers have: - It's an integer - It's a multiple of two - It lies between two odd numbers - Any number multiplied by it results in an even number (because 0 is even)
@aj-jc4cv
@aj-jc4cv Жыл бұрын
Entity component system rewrite would be super useful. These videos are gold.🏅
@m4rt_
@m4rt_ Жыл бұрын
21:45 I would create one class/struct for the Bird, and an enum for what type/color it is, then have some logic either inside the Bird, or in the use of the bird that changes the behavior based on the type/color... though I prefer the more C way of doing things over the C++ way.
@kgnet8831
@kgnet8831 Жыл бұрын
it is not a question of c versus c++ way ... with your implementation you could instanciate the birds as values, so std::vector or Bird[] (the c way) and get memory locality and that makes a c AND a c++ dev happy 😄
@necuz
@necuz Жыл бұрын
Right and if the only things that are going to differ between them is how score/lives changes on a collision, you can turn that into /blazing fast/ table lookups using the enum as index.
@m4rt_
@m4rt_ Жыл бұрын
@@necuz indeed
@Turalcar
@Turalcar 5 ай бұрын
@@necuz It won't be faster than grouping the birds by behaviour like the author does. I would extract a lot of the copy-pasted stuff though.
@darkthunder301
@darkthunder301 Жыл бұрын
Assuming all the classes from the birds to the sparks are obstacles the player needs to avoid, it might be easier to abstract the collisions into "check if player rectangle collides with generic object rectangle," whatever is used to represent the object is just a pretty dress for a box.
@xeridea
@xeridea Жыл бұрын
I vote for rewriting, you are very fast at code, you explain it anyway, which takes time. Less memory isn't always faster, in fact, many tasks perform better if you cache things so you aren't constantly recomputing, especially trig functions. If my game I cache square root values for my lighting system, giving a substantial speedup. Reducing code duplication can increase performance, since bloated code is less likely to fit in the CPU instruction cache, which is fairly small.
@mzxrules
@mzxrules Жыл бұрын
it really depends on the hardware whether code duplication is fast/slow, and also whether the problem necessitates that your code run fast. I've been recently coding an Atari 2600 game in 6502 asm, and the CPU is so slow (especially during rendering) that there are many instances where you'll waste several bytes of ram in order to save a few CPU cycles, either by unrolling loops (since conditional checks are slow) or avoiding modular solutions to problems (subroutines are slow and cost ram). If you're writing code in a high level language, the compiler is making it's own judgement calls on whether to duplicate code at the machine level anyway. In theory, that utils::Collisions function could be inlined everywhere it's called if the compiler deemed it efficient to do so, though I'm not confident if such a thing would be done in practice.
@MrHaggyy
@MrHaggyy Жыл бұрын
I have written code similar to the isEven number on purpose. We had 4 or 8 hardware ports and initialy there was a for loop iterating over i ports. The benefit of having 4 or 8 explicit is that i can check split second which of them where present at specific places in code. You couldn't mess around wirh the wrong hardware accidently and we didn't had to store the iterator in memory. But it's still good practice to keep things scalable. It's quite easy to make working code explicit once you have the necessary requirements to do so.
@StevenMartinGuitar
@StevenMartinGuitar Жыл бұрын
Would be cool to see the changes made and a diff. If people are concerned it would be too long then youtube has a super cool function where it lets you skip forward in a video
@megak550
@megak550 Жыл бұрын
Hello, can someone explain why the nesting is done? I mean std::vector.
@machimanta
@machimanta Жыл бұрын
This means that it's a vector containing unique pointers of type 'T', where T is from the 'template '. Templates are a form a "metaprogramming" where at compile time 'T' is expanded into whatever specific types actually use the implementation throughout the codebase
@Satook
@Satook Жыл бұрын
Seeing it done is always helpful. I think watching each tweak and how is actually really important.
@amoldhamale3202
@amoldhamale3202 Жыл бұрын
We need a dedicated video on cache hits and misses analysis
@stephenyork7318
@stephenyork7318 Жыл бұрын
Just up to 3:50. What comes to mind already is you could use some hash tables, Keyed by bird colour. Key by green then have the other colours that could be hot, the next key would return the scores.
@literallyfiction
@literallyfiction Жыл бұрын
Curious what your thoughts on Casey Muratori’s take on ‘clean code’, Cherno
@jamesmnguyen
@jamesmnguyen Жыл бұрын
Cherno would probably agree on some points but not others but hard to say exactly.
@designator7402
@designator7402 Жыл бұрын
0 does fulfill all requirements of being an even integer, so yes, 0 is considered even in most circumstances.
@usernamechefunziona373
@usernamechefunziona373 3 ай бұрын
3:20 How do you do that black magic?
@avtem
@avtem Жыл бұрын
13:00 lmao, it made my day edit: please keep talking about memory it's really interesting
@stephanweinberger
@stephanweinberger Жыл бұрын
@5:30 why so complicated? Just use polymorphism, i.e. different Bird-classes. Then the main code would be completely generic for a collision with _any_ type of Bird.
@larryd9577
@larryd9577 Жыл бұрын
I'm very keen on seeing the impact of the refactoring considering cache-hits/-misses.
@lombeelo8780
@lombeelo8780 Жыл бұрын
As example, to show the answers, you can rewrite code and show diff/two windows with two versions of file and describe the changes.
@Asto508
@Asto508 Жыл бұрын
Second video I've seen of you and although I'm not learning anything new in particular, I think it's nice to see someone else having similar thought processes going on when looking at this code. As others have highlighted, it would have actually been interesting to profile this code against a refactored version of it to see whether locality rolls out the way you (and I) assume it does. I've written similar stuff in the past using vectors holding unique_ptr without really thinking about the implications on the memory layout, but I haven't touched C++ in almost a decade to be honest, so a direct comparison for this particular case would actually be very nice.
@KuroKazeZX
@KuroKazeZX Жыл бұрын
well i already know not to repeat myself, it is more fun to see what you change to make it cleaner and possibly more efficient
@dougpark1025
@dougpark1025 Жыл бұрын
Tools at your disposal for solving the problems in this video. Inheritance, as you mentioned, making things derive off of a base class where you have common interfaces. Templates. If you can't or don't want to use abstraction, a template for something like your collide function could be implemented that assumes certain methods are in a class. This could be ever so slightly faster than inheritance, but maybe doesn't give you the nicety of changing how something works on a per derived class basis. Functional programming, lambda etc. This can be useful if for example you need a different way of detecting collision, same idea as doing a std::sort. One or another of these isn't necessarily the best way way. The locality in memory of data is an often missed performance improvement. Does the application create and destroy objects often enough to need pointers? Maybe the overhead of adding and removing items from a contiguous block of memory isn't as much as you think. That needs a benchmark to decide. My gut instinct is to start with contiguous memory. But that may not be the right answer. std::vector has a reserve option for if you need to grow a contiguous block. One of my standard optimization techniques is to collect then process, often with a sort involved to speed up processing. This may or may not be appropriate in all cases. The locality in memory idea goes back to the days when computers often didn't have enough memory to store all of the data being processed. Back in those days, before most of you were born, a lot of data was stored on disk then read into memory in blocks processed, then the results were written back out. If you think of your memory as a slow hard drive or an Internet connection, then you are on the right track to understand the concept.
@danielbaulig
@danielbaulig Жыл бұрын
12:20 Quick point of feedback. My understanding is that you build game engines and for engines and other pieces of product infrastructure it appears performance probably always beats readability and other maintainability factors. The idea is I guess that you can't know how your engine will get used in an actual product and how much real performance that product will need. However, when building products (instead of infrastructure), there is a sufficient level of performance at which point trading more performance for other factors like maintainability, readability, etc becomes utterly useless and will be net negative for the product and it's users. Just something I wanted to call out. More performance is not always better. I'm sure you're aware of this, but I think it's worth calling out to the audience, too.
@humanrye8696
@humanrye8696 Жыл бұрын
Right, without maintainability code get rotten very fast. The cost of development for every bugfix, every new feature skyrockets and the entire solution becomes unusable at some point. Performance focused code can still be used, but it should be easily replaceable if needed and should not affect higher layers.
@CallousCoder
@CallousCoder Жыл бұрын
All those else if's could be done even without a modulo by just doing a logical and 1. This is actually what most compilers optimize it as as well! I frankly don't understand how people even come up with such an incredible long else if list! But they are there!
@briannoel7398
@briannoel7398 3 ай бұрын
Maybe some demonstration with pseudocode would be useful, but I don't think a full implementation would be necessary. You're very good at explaining these things so I don't have trouble following along.
@brendandower9021
@brendandower9021 2 ай бұрын
Yes to re-writing. perhaps in a dedicated series. The Code Refactor series.
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
Thank you very much, Sir! Very well explained! What I love in special is that you address the aspect of readability of code among the importance to have a look at the memory consumption of the algorithm. These are very important topics! Well, since I‘m an embedded Developer - that one, that is use to dig in the "ancient mud" of cpu- and chip registers 😁 - I am used to work with *very* small Computersystems. Stuff with around 64kB and often less of SRAM! Not Gigabytes! KILO- Bytes! Often not more. Today’s PC based systems almost have x times of this memory available just for a Threads stack frame, what my System has as its whole…Furthermore these Systems run just with about 100 MHz! NOT GIGA Hertz ;-) So a clear SW architecture with the focus on performance and an economic memory layout is an absolute requirement on these Systems. Robustness: These Systems are used to run 24/7 for YEARS! Some of them are used in mission critical environments! Hence dynamic memory allocation (malloc/new…) are not used and are sometimes forbidden. However they are used very rarely - often allowed just at the startup of the system to allocate memory. The use of dynamic memory while runtime is not used due to the aspect of memory fragmentation. See I n an embedded System that runs 24/7 it is mandatory that your system will succeed memory allocations *at any time*. Hence on these Systems it is common to use objects/variables pre-allocated in the global memory space which are clearly allocated by the linker. Constant Data then is located in Non volatile and write protected memory areas (FLASH) and data, that need to be changed (Variables, working storage, arrays) are located in fast but sparse SRAM. Remember, we’ve gut just a view KILO Bytes of this in my world of Embedded computing. Nevertheless I‘m a big fan of C++ even on these small Systems. And believe me: All these prejudices about “bloat code due to C++” ( virtual functions with their indirection by vtables are wrong and I’ll need to argue that again and gain.. Just let you give you guys an insight of the life of an Embedded Engineer - a guy that life’s in the mud of code if you like 😊 And I can everybody recommend to grab an Arduino in order to see, how small a word can be - and how creative one can get just to get its code/idea to run on such a small/ weak system! Well, probably one may treat this as some sort of “stay in the monastery” for some months just to purify itself. Think about coding. Purify itself by enforces itself to consciously renounce and find another solution enforced by the limited resource... And I'm pretty sure! If one does so he/she will learn a lot! Things you'll always remember and be beneficial for your whole career! 😉 Servus Dirndl und Buam from Munich, Bavaria!
@jakeoshay
@jakeoshay Жыл бұрын
28:35, You definitely need to know if the bird is dead or not, so that if it's dead you would abort the check for collision so to not add more points than intended or retract lives when the entity should be already dead.
@shadeblackwolf1508
@shadeblackwolf1508 Жыл бұрын
For an inheritance_low implementation you could ofcourse just add an interface, not even a base class, allowing clustering them together. Delegate the hitbox to a hitbox object, reusing code isn't hard, and even if you don't like inheritance, that's not an excuse not to use composition instead
@maximalgamingnl9954
@maximalgamingnl9954 Жыл бұрын
Hi Yan, I have a question about the std::vector of std::unique_ptr's, because you said that the elements 'kind of had to' be heap allocated. It really seems like they don't, because of the vector itself behaving more or less as a smart pointer. Am I wrong?
@brunosilva-ed4pz
@brunosilva-ed4pz Жыл бұрын
13:16 Some big game devs should learn more about memory... (coff coff Hogwards Legacy coff coff)
@NotMarkKnopfler
@NotMarkKnopfler Жыл бұрын
I'd be very interested to see a re-implementation video. I've been told by others that my code is very easy to understand - but that's because I consciously try to make it as un-sophisticated as possible. Therefore I must admit, I would have taken a similar approach to the author. I found his code very easy to read though admittedly very repetitive - so I think you were quite correct to pick up on it. 👍Also, kudos to the author for 'sticking his head above the parapet'! I know it not really like that, but you know what I mean! 👍
@mr.anderson5077
@mr.anderson5077 Жыл бұрын
Hey Cherno, Amazing content!!! Please do a probably an hour long video on all the reviews you gave highlighting topics like Data oriented design, cache hits & misses, creating the inheritance system for all the similar components, optimization strategies, etc. We would love to see that in action and may be we'll pay you for investing your stream time. Its been ages since the beginning of this channel "FOR ANOTHER VIDEO..." is served proper justice for all the viewers. Everybody agreeing to that, plz hit the like below.
@AgentM124
@AgentM124 Жыл бұрын
Initially my thoughts on the separate vectors was maybe an explicit update order. Maybe obj of type X has to be updated before type Y. Perhaps you could sort a vector of all entity types by some priority P though instead. Or maybe collision has to be handled in a certain order. Update/render order imo should make sense implicitly. It should be some property of an entity, or its context that puts it before or after others. E.g. Z position could be a factor. Rather than explicitly handling different entities in different loops.
@JohnSmith-ze7sv
@JohnSmith-ze7sv Жыл бұрын
The game objects in the program I am writing are built upon ECS. The GameObject class is literally a wrapper for an ECS service which handles all of the component, entity and system mappings. A lot of C/C++ programmers really have a bent toward structural programming in the likes of low level API's.... But whenever I use those APIs - I typically just wrap them back up into objects anyway. I see why ECS is a thing. But developers appear to latch onto certain ideas like it was their bible and guiding princple - as opposed to what it really is. A temporary solution to a temporary problem.
@gilsonjustjr
@gilsonjustjr 4 ай бұрын
hi Cherno, which software do you use to write/draw on screen while you present? Thanks btw, thanks for the great content in C++ series !
@Bbdu75yg
@Bbdu75yg Жыл бұрын
That thumbnail was so funny!😂
@avtem
@avtem Жыл бұрын
Hey, Cherno! Would you like to do a video about outdating code? For example how game engine stops supporting a certain platform and what you do about that as the creator?
@maverikmiller6746
@maverikmiller6746 Жыл бұрын
This was pretty good. Thanks Chernoman.
@paulfrischknecht3999
@paulfrischknecht3999 Жыл бұрын
thanks for this. you should review code that looks good on the surface but could still be improved substantially, not something like this that obviously suffers simply from too much duplication
@roboterbasteln
@roboterbasteln Жыл бұрын
0 is an even number. But in C++, unlike some other languages like Python, modulo for negative numbers returns negative remainders.
@m4rt_
@m4rt_ Жыл бұрын
I would like to see you actually rewriting it
@AnFunctionArray
@AnFunctionArray Жыл бұрын
I would just use virtual functions in this context - for loops - become one function and we have collide_action (especially because we have opted to use unique ptrs).
@tambow44
@tambow44 Жыл бұрын
Is Zero an even number? Is zero even a number at all? The Mathematics department back in uni had a LOT of debates about this. Great lecture btw, ty Chernzy.
@powerpcx86
@powerpcx86 Жыл бұрын
You are the most wonderful cpp dev i know on KZbin, but when would you consider using rust as the ultimate cpp replacement ?
@onemoremagistr
@onemoremagistr Жыл бұрын
Really great! Thank you!
@bva0
@bva0 Жыл бұрын
Great video Cherno! I have a question regarding the implementation of your example of a contiguous vector of structures of position (pos) + velocity (ves) of each bird. Let's say that this vector is called pos_vel_vec. Now let's say you have to dynamically kill existing birds and add new birds, lots of times. How do you reutilize the positions of killed birds in the vector efficiently? Like, maybe set the velocity of a kill bird to zero then add the index of this killed bird in the array to a queue, which is then utilized to create new birds? If the queue is empty, use pos_vel_arr.push_back(). Main drawback is that you perform unnecessary calculations (assuming we want to avoid branching with a boolean mask of live birds). Another drawback maybe would be having to use a boolean mask.
@AntonioNoack
@AntonioNoack Жыл бұрын
In this case, the order of birds doesn't matter. Therefore, the best solution is to remove the last bird (just size--), and copy it onto the dead bird (effectively a memcpy of the size of one instance). If you iterate over the birds and kill them conditionally, you also can have a read and a write pointer, and just increment the wrote pointer on alive birds.
@AntonioNoack
@AntonioNoack Жыл бұрын
*write (I'm using YT on my phone, it's horrible 😱)
@scriptles
@scriptles Жыл бұрын
I love your video's, excellent work as usual. Keep up the good work teaching us.
@pederslothzuricho7685
@pederslothzuricho7685 Жыл бұрын
10:58 0 is not a number, neither even nor uneven, its a concept we pretend is a number to make maths work, 0 is in fact the absence of everything. Hence why you cannot divide by zero. when we zero-index, we actually use zero as 1 and pretend that absence doesn't exist. Absence of power in that sense is Zero, but numerically in binary terms we usually apply 0 as 1 and then pretend the 1 is a pretending of the absence we symbolise with 0. But zero is not a number it does not exist.
@Splntxx
@Splntxx Жыл бұрын
I know this is a bit offtopic for your normal videos, but could you make a video about shaderdebugging on windows? I can follow your explainations really good and I am struggleing with this topic at the moment :) great video btw!
@Stabby666
@Stabby666 Жыл бұрын
I guess just using return ((x&1)==0); for isEven is the most efficient as mod implies a division? I suppose any compiler would optimise to the bitwise test though.
@igorthelight
@igorthelight Жыл бұрын
You are correct!
@hbirler
@hbirler Жыл бұрын
((x & 1) == 0) is actually three instructions on x86: and, test, sete (~x & 1) is two instructions: not, and and yes any sane compiler generally understands what you meant however way you write it and generates the optimal code. Use compiler explorer to check!
@MrGeneralScar
@MrGeneralScar Жыл бұрын
Do you do LUA? I am always looking for better ways to do things, the problem is when I want to test code outside of a game I write it for (an addon), I have to change the code to standard LUA and then back again because the game apparently uses a different code base for LUA parsing to what is latest and greatest. They also have thier own functions that dont exist in normal LUA.
@Necessarius
@Necessarius Жыл бұрын
Thumbnail code is pretty and useful
@ladymushroom9485
@ladymushroom9485 9 ай бұрын
10:00 if else is to slow for use cases like these. Optimize with a switch statement.
@anon_y_mousse
@anon_y_mousse Жыл бұрын
I know what you're trying to say with optimizing, but an IsEven function should be a macro that just does &1 on the input to test. Also, as long as it can tell what you're trying to do, every modern compiler will optimize %2 into &1, so any possible debate about using mathematical operations versus unrolling a loop are completely pointless.
@TheKinderNinja
@TheKinderNinja Жыл бұрын
10:20 You can check whether a number is even this way if(!(num&1)). It's much faster than division.
@zdspider6778
@zdspider6778 Жыл бұрын
if ((num % 2) == 0) // is even if ((num % 2) != 0) // is odd
@TheKinderNinja
@TheKinderNinja Жыл бұрын
@@zdspider6778 I know. I thought the bitwise and operation would by faster. I just tested it. It turns out it's not actually faster on my computer.
@user-zu1ix3yq2w
@user-zu1ix3yq2w Жыл бұрын
@@TheKinderNinja is that due to compiler optimizations?
@TheKinderNinja
@TheKinderNinja Жыл бұрын
@@user-zu1ix3yq2w idk I tested it setting the compiler to "Debug", so it's likely not the optimisation. I should test it in assembly.
@AmrHendawy-g5u
@AmrHendawy-g5u Жыл бұрын
What is the name for this color them because it is so good
@igorthelight
@igorthelight Жыл бұрын
Looks like Darcula most likely ;-)
@AmrHendawy-g5u
@AmrHendawy-g5u Жыл бұрын
@@igorthelight I know darcula, it is not it.
@useronuralp
@useronuralp Жыл бұрын
Great vid as always Yan
@thev01d12
@thev01d12 Жыл бұрын
Would love to see you refactor this into something more scalable and optimized.
@MasterHigure
@MasterHigure Жыл бұрын
"hey what's up guys my name is China welcome back to code review Series" Auto-generated captions for the win.
@IamusTheFox
@IamusTheFox 3 ай бұрын
I spent way too long trying to over-engineer a better solution to IsEven. All it needed was constexpr and a modulo operator. lol.
@mahfuzkabir7812
@mahfuzkabir7812 Жыл бұрын
Please do a video on actually implementing your changes!
@FlotzOnYou
@FlotzOnYou Жыл бұрын
The "IsEven" function is priceless
@robertlever
@robertlever Жыл бұрын
i would realy apriciate an explenation on enteties and how to implement it just for educational purpuses dont neeed the code but a nice drawing of it :D
@easyBob100
@easyBob100 Жыл бұрын
10:38 "mod 2 == 0" ..... try for isOdd: return (number & 1); Faster to just AND the LSB and return it IIRC. (Note: been a while, might be 'wrong', but the idea is right) :)
@arcanium_walker
@arcanium_walker Жыл бұрын
Idea is right, but in the C# world this is return 1 (And the C# not convert automatically to a Boolean type. In C#: (number & 1) != 1 ). But in C++ context the solution is faster than mod by 2. (I think) :D I prefer this method in some cases.
@Lord2225
@Lord2225 Жыл бұрын
It isnt. Every optimizer out there will optimize mod 2 out to fastest possible expression for given hardwere and additionaly it is not guaranteed that &1 will be any faster, but for sure less readable.
@easyBob100
@easyBob100 Жыл бұрын
@@Lord2225 If you can't read basic boolean operations, maybe programming isn't for you. ;) Seriously though, compilers don't always get things right, especially for more complicated things, so knowing things like this can save you clock cycles. I get what you're saying though. :)
@easyBob100
@easyBob100 Жыл бұрын
@@arcanium_walker Yeah I wasn't sure, and I don't program in C# either. I just don't like putting the if inside the isOdd function when you know the user of the function is putting it inside their own if statement. :D
@Lord2225
@Lord2225 Жыл бұрын
​@@easyBob100 Or it will add few. Early optimalizaton is source of all evil. These kinds of micro "optimalizations" come from very early days of C and Pascal when optimizer wasnt very versatile, together with other vestiges like declaring varibles before assigning them ect. Stop this. Write clean code.
@Keltheran
@Keltheran Жыл бұрын
For the even number check I prefer return !(number & 1); and yes, it is just to annoy people who reads it 🙂 it is also probably the lowest amount of CPU instructions for the problem, though I do believe the compiler will change the mod into it (have not checked that though).
@hbirler
@hbirler Жыл бұрын
GCC actually generates ((~number) & 1) for either code in order to perfectly generate the values 0 or 1 without having to "cast" (number & 1) to boolean. (And ((~number) & 1) is definitely faster than branching, especially since in this case the branch would likely be unpredictable.)
@Keltheran
@Keltheran Жыл бұрын
@@hbirler And that is why you should almost always trust the compiler. My example didn't have any branches though, "! int" is branch-less since it uses the zero flag to set the resulting value, it uses more instructions than the bit flip though so the compiler wins again. Although with branching you might mean the if/else stack?
@meyou578
@meyou578 Жыл бұрын
can you make tutorial of how to implement language server protocol
@rafa_br34
@rafa_br34 Жыл бұрын
Great video as always!
@akbarisroilov1002
@akbarisroilov1002 Жыл бұрын
Hey Cherno
@timturner7609
@timturner7609 2 ай бұрын
I'm probably not your target audience, but I'd much rather see videos where you move quicker like "this is bullshit. Something like this would be better." And then through the magic of editing you fix it and hit the highlights of why your fix is better than the original. I'm an old dog but I'm always hoping to learn a new trick
@trevthea5781
@trevthea5781 Жыл бұрын
Looking forward to more chat gpt code reviews.
@igorthelight
@igorthelight Жыл бұрын
Especially ChatGPT Plus (based on much more "smart" GPT-4) ;-)
@TheCodingHubYT
@TheCodingHubYT Жыл бұрын
Great video!
@draconicepic4124
@draconicepic4124 Жыл бұрын
The first thing I thought when I saw the code was: the Instruction Cache isn't happy.
@igorthelight
@igorthelight Жыл бұрын
Every newer CPU has more cache! Programmers: You underestimate my code-monkey powers! ;-)
@Simple_Simon_UK
@Simple_Simon_UK Жыл бұрын
Write the code to improve. Much more useful.
@oleksiistri8429
@oleksiistri8429 Жыл бұрын
9:50 actually, i have such code in my projects, lol, maybe not with even/odd and true/false, but a lot of ifs comparing with number somewhere up to 35 )))
@DarthJane
@DarthJane Жыл бұрын
An inheritance based system is bad in a vector anyway, as it needs 2 redirections. For example you have classes A and B where B inherits from A both shoved into a vector it would first get an object which tells the computer which of the two it actually is with another pointer to the actual object. Otherwise it would need to either allocate enough space to hold the biggest object, which is very wasteful, and doesn't work well with precompilation and libraries, or override parts of objects, which would cause a lot of those being junk.
@HenryLoenwind
@HenryLoenwind Жыл бұрын
10:30 modulo 2? Why waste so many CPU cycles? "return !(x && 1);" is so much faster. Save two extra instructions in half the cases by having isOdd() instead, when isEven would need to have a "!" both inside and outside the call. (Although right-shifting into carry and then branching on carry would be even faster...but that cannot be put into a function.) 14:30 My example is the old file drawer. If everything that you need for your work is in one file drawer within your reach, is that faster than when you have a huge warehouse of file drawers with everything spread out? The same is true for computer memory. If everything the CPU needs is in the cache (i.e. "in reach"), it is faster than when it has to fetch it from the RAM sticks on the other side of the motherboard.
@pwhqngl0evzeg7z37
@pwhqngl0evzeg7z37 Жыл бұрын
For isEven, you should just use mod. Any reasonable compiler will optimize this for you, and it's more readable than a manual optimization, which I guess may not even be best if the compiler can find a better optimization using a special opcode or something for checking mod2 specifically.
@EraYaN
@EraYaN Жыл бұрын
Removing the jumps between the multiple vectors in memory and replacing them with virtual function lookups might still not be that great with this low amount of entity types.
@gianbattistavivolo7449
@gianbattistavivolo7449 Жыл бұрын
What's your visual studio theme?
@igorthelight
@igorthelight Жыл бұрын
Looks like Darcula but I may be wrong
@ThePowerRanger
@ThePowerRanger Жыл бұрын
I love these videos.
@kurt7020
@kurt7020 Жыл бұрын
We shouldn't iterate through them, we should use recursion and pure functions to allocate a completely new copy every time we change a property value. XD
@wjrasmussen666
@wjrasmussen666 Жыл бұрын
Hey Cherno!
@cpp_medium_rare3474
@cpp_medium_rare3474 Жыл бұрын
Something that baffles me is that we are in 2023 and we still have people "learning" to dynamically allocate everything in C++. It's not the first time I see these vectors of utterly pointlessly dynamically allocated objects. Every single member of that class should've been stack allocated. Even the "Sparks" instances that derives from "Explosion" are still just in a container by themselves, so... "vector" for crying out loud! And, yes, I understand the argument that should these derive from a base class, then the code would make more sense but that's not the case here. And, again, even the one class that derives from a base class has its own container anyway. What person or what book is still teaching beginners to do that? I sincerely would like to know.
@JohnSmith-ze7sv
@JohnSmith-ze7sv Жыл бұрын
Higher level languages are where most people are being on-boarded into programming these days I'd imagine. Everything's an object. Stack and heap allocation just aren't concepts you're aware of comming from those languages. If one could use smart pointers to replicate ones own javascripting prowess in C++ - I can see how that approach would be taken.
@cpp_medium_rare3474
@cpp_medium_rare3474 Жыл бұрын
@@JohnSmith-ze7sv In this instance, what prowess needed replication?
@JohnSmith-ze7sv
@JohnSmith-ze7sv Жыл бұрын
@@cpp_medium_rare3474 I never meant prowess from an objective viewpoint.
@DarthJane
@DarthJane Жыл бұрын
I don't get why IsOdd should use modulus, it's an int, so just do 'return value & 1'. Way faster, and still obvious (I'd actually claim more obvious than using modulus is)
@pwhqngl0evzeg7z37
@pwhqngl0evzeg7z37 Жыл бұрын
Probably not more obvious, since there's probably more programmers who understand remainders than those who understand integer representation. And it'a definitely not faster unless you compile with -O0
@acelyon5221
@acelyon5221 Жыл бұрын
Ngl I hate seeing repeated code, I end up finding myself making some kind of repeated code and eventually it bothers me and I have to rewrite and try to make it better.
@Manas-co8wl
@Manas-co8wl Жыл бұрын
Hey Cherno. Y’have no idea the journey I went through. It was like an Alice in Wonderland journey trying to find a new language: Python, js, rust, Nim, julia, lua, haxe… and guess what. I came back here to stay. Ultimately found them all lacking in one area so much. I might continue using Haxe because of it ability to transpile, but at this point I’m so frustrated that I want to make my own transpiler that writes to cpp and create automatic bindings for higher languages. Like at this point that seems to be the way. Anyway.. hi. How was LD53? Came back to stay. Needed someplace to rant and I don’t know why I chose here but we’re back to cpp. Man finding a good language is so hard..
@phitc4242
@phitc4242 Жыл бұрын
do one thing, but do it right :D
All about MEMORY // Code Review
33:42
The Cherno
Рет қаралды 168 М.
2000 HOUR 2D Game Engine! // Code Review
32:01
The Cherno
Рет қаралды 90 М.
Disrespect or Respect 💔❤️
00:27
Thiago Productions
Рет қаралды 38 МЛН
Увеличили моцареллу для @Lorenzo.bagnati
00:48
Кушать Хочу
Рет қаралды 7 МЛН
Кто круче, как думаешь?
00:44
МЯТНАЯ ФАНТА
Рет қаралды 4,3 МЛН
BETTER Header Files and Preprocessor Debugging
24:26
The Cherno
Рет қаралды 74 М.
CHESS! // Code Review
51:05
The Cherno
Рет қаралды 241 М.
5 Python Libraries You Should Know in 2025!
22:30
Keith Galli
Рет қаралды 12 М.
RAY TRACING! // Code Review
58:32
The Cherno
Рет қаралды 152 М.
Tailscale: NETWORKING MAGIC!
25:51
Level1Techs
Рет қаралды 29 М.
This tool annoyed me (so I built a free version)
19:38
Theo - t3․gg
Рет қаралды 127 М.
Why Didn't He Get the Job? Let's Find Out! // Code Review
27:25
The Cherno
Рет қаралды 146 М.
TERMINAL GAME ENGINE! // Code Review
23:59
The Cherno
Рет қаралды 74 М.
I Rewrote This Entire Main File // Code Review
16:08
The Cherno
Рет қаралды 176 М.
Dear Functional Bros
16:50
CodeAesthetic
Рет қаралды 549 М.