The Importance of Scalable Code // Code Review

Поделиться
HTML-код
  • Опубликовано: 30 сен 2024

Комментарии • 247

  • @TheCherno
    @TheCherno  Год назад +12

    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 Год назад +376

    I would absolutely like to see you actually implement the things you talk about.

    • @hourglass2836
      @hourglass2836 Год назад +2

      this

    • @ultimatesoup
      @ultimatesoup Год назад +1

      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 2 месяца назад

      ​@@ultimatesoup That isn't what any half-competent game does tho

    • @JOHN-um2
      @JOHN-um2 12 дней назад +1

      That’s the thing. Half the things he says don’t come to fruition in a real environment due to constraints and HIS IDEAS SUCK.

  • @CatzHoek
    @CatzHoek Год назад +174

    Maybe not always but it would be cool to see the actual code you would produce for certain things once in a while.

  • @Dr-Zed
    @Dr-Zed Год назад +247

    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 Год назад +45

      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 Год назад +10

      @@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 Год назад +5

      It's missing the "- resilient code"

    • @Dr-Zed
      @Dr-Zed Год назад +3

      ​@@rafa_br34 updated the list

    • @peezieforestem5078
      @peezieforestem5078 Год назад +6

      adjectives are all well and good, but what about "zero code"? I heard it's the next big thing.

  • @Squirrelies1
    @Squirrelies1 Год назад +30

    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.

  • @stephenelliott7071
    @stephenelliott7071 Год назад +52

    An Entity Component version would be very helpful, as would performance profiling with cache misses vs the current code IMO.

  • @ale-lp
    @ale-lp Год назад +70

    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.

  • @urugulu1656
    @urugulu1656 Год назад +16

    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 Год назад +2

      I was thinking same thing. All birds the same class, but just reference an array based on bird type for values.

    • @legitjimmyjaylight8409
      @legitjimmyjaylight8409 Год назад +1

      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 5 месяцев назад

      You should use inheritance here if you want to do it in a more C++ way.

    • @nevemlaci2486
      @nevemlaci2486 2 месяца назад

      ​@@yiranmushroomdoing it with inheritance is very inefficient tho, loads of cache misses 🤷‍♂️

  • @РайанКупер-э4о
    @РайанКупер-э4о Год назад +16

    I would love to see this code actually modified using your recommendations.

  • @Domix-nh8ws
    @Domix-nh8ws Год назад +13

    Please rewrite it with an ECS, or something similar it would be amazing to see the comparison.

  • @fyvefouroh
    @fyvefouroh Год назад +16

    You should use a tool that measures cache hits and misses on this project for fun. I think it would be interesting to see

  • @literallyfiction
    @literallyfiction Год назад +4

    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.

  • @m4rt_
    @m4rt_ Год назад +12

    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 Год назад +2

      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 Год назад +5

      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 3 месяца назад

      @@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.

  • @BulletproofOutlaws
    @BulletproofOutlaws Год назад +17

    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

  • @stephanweinberger
    @stephanweinberger Год назад +2

    @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.

  • @Treborbobuk
    @Treborbobuk Год назад +7

    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!

  • @designator7402
    @designator7402 Год назад +4

    0 does fulfill all requirements of being an even integer, so yes, 0 is considered even in most circumstances.

  • @kingx1180
    @kingx1180 Год назад +6

    Yandere dev moment

  • @aj-jc4cv
    @aj-jc4cv Год назад +4

    Entity component system rewrite would be super useful. These videos are gold.🏅

  • @darkthunder301
    @darkthunder301 Год назад +1

    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.

  • @omarmagdy1075
    @omarmagdy1075 Год назад +11

    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.

  • @APaleDot
    @APaleDot Год назад +1

    > 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)

  • @brunosilva-ed4pz
    @brunosilva-ed4pz Год назад +1

    13:16 Some big game devs should learn more about memory... (coff coff Hogwards Legacy coff coff)

  • @HenryLoenwind
    @HenryLoenwind Год назад +2

    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.

  • @StevenMartinGuitar
    @StevenMartinGuitar Год назад +2

    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

  • @Simple_Simon_UK
    @Simple_Simon_UK Год назад +1

    Write the code to improve. Much more useful.

  • @xeridea
    @xeridea Год назад +3

    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.

  • @m4rt_
    @m4rt_ Год назад +2

    I would like to see you actually rewriting it

  • @danielbaulig
    @danielbaulig Год назад +1

    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.

  • @paulfrischknecht3999
    @paulfrischknecht3999 Год назад +1

    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

  • @maximalgamingnl9954
    @maximalgamingnl9954 Год назад +1

    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?

  • @AmrHendawy-g5u
    @AmrHendawy-g5u Год назад +1

    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.

  • @eboatwright_
    @eboatwright_ Год назад +1

    Roses are red,
    This grabbed your attention,
    The meme in the thumbnail,
    is at 9:47

  • @timturner7609
    @timturner7609 16 дней назад

    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

  • @Stabby666
    @Stabby666 Год назад +2

    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!

  • @briannoel7398
    @briannoel7398 2 месяца назад

    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.

  • @cpp_medium_rare3474
    @cpp_medium_rare3474 Год назад +1

    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.

  • @SirMedvind
    @SirMedvind Год назад

    first of all this way you only need to type half as much.
    private bool IsEven(int number){
    if(number == 1) return false;
    else if(number == 3) return false;
    else if(number == 5) return false;
    else if(number == 7) return false;
    else if(number == 9) return false;
    else if(number == 11) return false;
    else if(number == 13) return false;
    ...
    else return true;
    }

  • @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.

  • @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.

  • @treelibrarian7618
    @treelibrarian7618 Год назад

    inline bool isEven(int number) { return !(number&1); }
    sorry. I couldn't not.
    and yes, it's faster than any number of branches, even just one.

  • @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 )))

  • @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.

  • @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.

  • @gilsonjustjr
    @gilsonjustjr 2 месяца назад

    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 !

  • @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

  • @electronlabs2802
    @electronlabs2802 Год назад

    So lets say birds are inherited from Abstract bird... And there is a method that only exist on black birds .. you made collection of abstract birds and you lost the child type .. how would you implement the dispatcher without type check and down casting

  • @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

  • @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 2 месяца назад

    I spent way too long trying to over-engineer a better solution to IsEven. All it needed was constexpr and a modulo operator. lol.

  • @ziccodx
    @ziccodx Год назад

    What do you mean? It's a ladder of ifs how is a ladder not scalable 😇
    fyi I'm just joking

  • @REktSigMa
    @REktSigMa Год назад

    LOL This could be a complete data base of the element "Bird_Types" LOL

  • @brendandower9021
    @brendandower9021 29 дней назад

    Yes to re-writing. perhaps in a dedicated series. The Code Refactor series.

  • @user-stanrbm
    @user-stanrbm Год назад

    У вас фамилия Черников? Вы русский? Ваш отдельный канал называется Ян Черников. Молодец! 🙂Вы отлично владеете английский язык и программирование. 👍

  • @deltaghostprofessionalgame875
    @deltaghostprofessionalgame875 25 дней назад

    I hate this kind of code! tidy or whatever I don't like it.....

  • @coolcodingcat
    @coolcodingcat 2 месяца назад

    This code makes my head spin. There is way too much going on in each class and inside each method.

  • @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

  • @Luke-nj8pf
    @Luke-nj8pf Год назад

    Can you do a developer react video talking about tears of the kingdom’s engine ?

  • @twiksify
    @twiksify Год назад

    Code rewrite is not really needed as you already have excellent tutorials on the language and related best practice.

  • @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!

  • @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.

  • @ArtofBen
    @ArtofBen Год назад +1

    I am just waiting for the day someone asks me how to write an isOdd function. return number & 1;

  • @ladymushroom9485
    @ladymushroom9485 7 месяцев назад

    10:00 if else is to slow for use cases like these. Optimize with a switch statement.

  • @Necessarius
    @Necessarius Год назад

    Thumbnail code is pretty and useful

  • @oguzhantopaloglu9442
    @oguzhantopaloglu9442 Год назад

    bro puts a brilliant ad but doesnt know that zero is even 💀

  • @dashdroptv
    @dashdroptv Год назад

    Captions: "hey what's up guys my name is China"

  • @MeriaDuck
    @MeriaDuck Год назад

    That thumbnail. Wut!? Please no.

  • @nikolaoslibero
    @nikolaoslibero Год назад

    You might have more time without all the meta-tangents.

  • @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.

  • @harishthotakura857
    @harishthotakura857 Год назад

    Wut do u mean by that my code perfectly execute ;)

  • @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! 👍

  • @gigantopithecus8254
    @gigantopithecus8254 Год назад

    Wouldn’t doing and with one be faster

  • @Chernoalphafan
    @Chernoalphafan Год назад

    Why does he look like MrBeast if he was 45

  • @usernamechefunziona373
    @usernamechefunziona373 2 месяца назад

    3:20 How do you do that black magic?

  • @putrescentvermin
    @putrescentvermin Год назад

    That thumbnail instantly reminded me of Yanderedev. On a real note, this is important because in games like GTA V which is a huge example of scope/feature creep, you want to make it modular in case if you want to add features long term.

  • @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.

  • @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).

  • @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.

  • @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.

  • @roboterbasteln
    @roboterbasteln Год назад

    0 is an even number. But in C++, unlike some other languages like Python, modulo for negative numbers returns negative remainders.

  • @zdspider6778
    @zdspider6778 Год назад

    You talk about scalability and prioritizing runtime performance over "pretty code", but advocate for splitting things into functions. 🤨 Each function call has an overhead. Try declaring them as _consteval_ (C++20) and see if you can optimize them that way at compile time. If you can't, because the compiler doesn't let you, it means it has a cost associated with it, in which case it's better to have larger (and fewer) functions, rather than more functions that are shorter. To reduce the number of function calls.
    27:06 vtables and indirection ARE bad, if you want it to scale. That 0.001ms performance penalty (in addition to the work without it) may not seem like much for 100 objects, or 1000, but if you want 10.000.000, then it definitely will.

    • @pwhqngl0evzeg7z37
      @pwhqngl0evzeg7z37 Год назад

      I hope there's a way to make long functions readable, because that tends to be one of the most egregious examples of revolting code that I've seen. I get if you need it for performance, but I'd prefer writing readable code first and then only optimizing out jumps when you've measured the performance and you've eliminated other possibilities.

  • @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.

  • @Affje800
    @Affje800 Год назад

    Please please rewrite this option. I think it is fine when tell us how you would do things. But I think that (especially for beginners) it would be really beneficial if they could see the difference (literally).

  • @thev01d12
    @thev01d12 Год назад +1

    Would love to see you refactor this into something more scalable and optimized.

  • @powerpcx86
    @powerpcx86 Год назад

    You are the most wonderful cpp dev i know on RUclips, but when would you consider using rust as the ultimate cpp replacement ?

  • @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.

  • @legitjimmyjaylight8409
    @legitjimmyjaylight8409 Год назад

    I don't like the code, it could be structured way better. Functions are way too long, some more polymorpism and more modulation and the naming, like why is a vector of black birds named as black bird, like only 1 black bird!?, etc.

    • @pwhqngl0evzeg7z37
      @pwhqngl0evzeg7z37 Год назад

      This is an interesting question that I find myself asking often when I name collections. Of course, the object itself is a collection of birds, so it makes sense that the name is plural. But at the same time, I like "bird[0]" because it reads like "bird number 0", rather than "birds[0]".

  • @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.

  • @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.

  • @testTest-to8di
    @testTest-to8di Год назад

    You could explain some things and than you can skip the video and just show us how shoud be done, with that, the video won't be long.

  • @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.

  • @masterbonzala
    @masterbonzala Год назад

    zero is even, come at me mathematicians

  • @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

  • @larryd9577
    @larryd9577 Год назад

    I'm very keen on seeing the impact of the refactoring considering cache-hits/-misses.

  • @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

  • @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.

  • @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?

  • @akbarisroilov1002
    @akbarisroilov1002 Год назад +1

    Hey Cherno