Can we use JavaScript to go faster than C++ in Ladybird?

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

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

  • @lionkor98
    @lionkor98 6 дней назад +1

    These are interesting beyond any reason, thank you so much for making them still. Been here for over 4 years when i had just started uni, your videos of you in the car inspired me a lot. I adopted your C++ style and a lot of the commit etiquette, and of course changed it to fit my needs. I'm happy in a job now, finished uni, and am married, and I think these videos are one of the few things that keeps bringing me joy and gives me new things to learn, even if they're small things sometimes.
    Thanks for making these. I doubt you remember my comments from 4 years ago, you responded to them, I always had a good time here :)

    • @awesomekling
      @awesomekling  6 дней назад +1

      Hi Lion! Glad to see you're still here, all grown up with a job and wife! Congratulations on making it

    • @lionkor98
      @lionkor98 5 дней назад

      Thank you!!! I appreciate that - and you came so far, too!

  • @pixl_xip
    @pixl_xip Месяц назад +86

    "And the sausage stops growing" Never heard that one

  • @egemengol306
    @egemengol306 Месяц назад +123

    "Implement parts of our JS engine in JS and gain performance benefit from it"
    ...writing down to my notebook of sentences that have not been uttered ever

  • @Whateverworksism
    @Whateverworksism Месяц назад +54

    Thanks for all you do Andreas and also thanks for uploading to youtube, I enjoy it. I wish you a good weekend.

    • @awesomekling
      @awesomekling  Месяц назад +14

      Thanks for stopping by! I wish you a good weekend as well

    • @theevilcottonball
      @theevilcottonball Месяц назад

      \x1b[0;30mIs this how you do it?

    • @theevilcottonball
      @theevilcottonball Месяц назад

      color now?.

    • @theevilcottonball
      @theevilcottonball Месяц назад

      How did you color :^) and how did you do it that when I copy it I only get "caret"

    • @pp00ww
      @pp00ww Месяц назад +1

      @@theevilcottonball You have to become a channel member to use that emoji.

  • @relakin
    @relakin Месяц назад +24

    Yes! Finally got an hour long video. There is no other channel that I can just sit and watch someone for an hour straight and still wish that the video was longer. Thanks for posting!

  • @sammmba
    @sammmba Месяц назад +53

    Careful with the `typeof R === 'object'` because in javascript `null` is also an object!

    • @REALsnstruthers
      @REALsnstruthers Месяц назад +20

      interestingly enough, this is actually more of a misfeature than a bug. in the earliest javascript engines, there was a feature called “liveconnect” which allowed for direct interoperability with java classes. unfortunately, because all java objects are nullable & in spite of javascript already having undefined (in practice if not necessarily defined as a keyword until quite a bit later), javascript ended up with an empty, nonexistent object called null which, entirely for long-defunct interoperability reasons, has a typeof object

    • @JannisAdmek
      @JannisAdmek Месяц назад +2

      @@REALsnstruthers fantastic comment - thanks for sharing that info!

    • @kreuner11
      @kreuner11 Месяц назад +2

      @@REALsnstruthers this doesn't appear to be accurate. liveconnect is a library rather than a language feature. the explanation I saw from the creator of JS was that null meant an object with a pointer of 0, akin to NULL in C in which it was written

    • @REALsnstruthers
      @REALsnstruthers Месяц назад

      @@kreuner11 browsing the netscape archives of the internet archive, liveconnect was a feature that was used as part of their browser integration with java, including with applets

  • @solcloud
    @solcloud 24 дня назад

    very cool experiment! I remember recommending this some time ago so I am really interesting to see how it would go

  •  Месяц назад +1

    My initial thought when seeing the JS was to use an array and join them instead of doing the string manipulation for every flag, you then mentioned the string concat exactly when I was about to comment so you were ahead of me 🤠

  • @RubenKelevra
    @RubenKelevra Месяц назад +24

    I mean, you could also compile those to byte code while compiling lb, so you don't have to compile them to byte code on execution. :)

    • @Daktyl198
      @Daktyl198 Месяц назад +10

      I'm sure he knows. This sounded a whole lot more like a "I wonder if this would work" type of thing.

  • @kingkonefpv4553
    @kingkonefpv4553 Месяц назад

    Thanks that was very amusing! i wrote a lot of js when node was new and you still had to use brains to make it run fast in the browser.

  • @anatolii1013
    @anatolii1013 Месяц назад

    Very good stuff to learn something interesting. Thanks for it!

  • @GabrielSoldani
    @GabrielSoldani Месяц назад +24

    Just curious, why not make object_get from C++ benefit from the cache instead? It’s probably even faster, and speeds up every call rather than just the ones on this specific built-in you’ve ported.

    • @Bobbias
      @Bobbias Месяц назад +2

      That was my thought too. But still, performance isn't really the current top priority, and if it turns out in the future that this code ends up as a candidate for optimization in the future maybe it will eventually be rewritten in C++ with better optimizations.
      I think this was really just intended as an experiment (and something that would make for a good video).

  • @somebodystealsmyname
    @somebodystealsmyname Месяц назад +24

    The bitmask optimization should go into LB regardless of the other tests you did.

    • @awesomekling
      @awesomekling  Месяц назад +15

      Certainly yeah, just gotta clean it up!

    • @somebodystealsmyname
      @somebodystealsmyname Месяц назад +2

      @@awesomekling That optimization was not that hacky, should be easy to polish up.

    • @qwerty123443wifi
      @qwerty123443wifi Месяц назад

      ​@@awesomekling you can also use popcount (number of high bits) to allocate the right amount of bytes

  • @knobbymcfeck
    @knobbymcfeck Месяц назад +22

    Don't those flags need to be left-shifted on creation, or in the enum? It's been ages since I did C++, so maybe I'm misunderstanding...?

    • @awesomekling
      @awesomekling  Месяц назад +25

      Oh yes, you are absolutely right! So the code was buggy. With that fixed, performance doesn’t change though :) Great observation dude!

    • @knobbymcfeck
      @knobbymcfeck Месяц назад +1

      @@awesomekling Woohoo! Thanks! For everything! I love these videos, thank you so much, tussentack!

    • @pulmonary_yoghurt
      @pulmonary_yoghurt Месяц назад

      I also noticed that, seems like I wasn't the first one though 😸

    • @GundersenMarius
      @GundersenMarius Месяц назад +1

      Good thing he has a copilot to copilot 😅

  • @miko007
    @miko007 Месяц назад +11

    i may be missing something here, but if those flags are basically immutable after the regexp object is created, why dont you build that string on object creation and just ask for it later?
    you could even build a lookup table with all possible strings and use that bitfield to index it. then you just can return a reference to the string and save on memory big time

  • @su1cedek
    @su1cedek Месяц назад

    Thank you, I was missing your longer videos

  • @StevenHokins
    @StevenHokins Месяц назад

    Very interesting, thank you for video of prototyping this

  • @ninadsachania3652
    @ninadsachania3652 Месяц назад +13

    Nice video, AK!
    Why did you change your OS from Linux to macOS? Just curious.

    • @awesomekling
      @awesomekling  Месяц назад +18

      I really missed the Instruments profiler, so I bought a MacBook Pro and started using it :)

    • @ninadsachania3652
      @ninadsachania3652 Месяц назад +5

      @@awesomekling I also noticed that you started using a debugger instead of printf() debugging. What changed?

    • @awesomekling
      @awesomekling  Месяц назад +16

      Trying to use some new tools! But I still use printf debugging every day :)

    • @ash8128
      @ash8128 5 дней назад

      @@awesomekling I've noticed you specifically used "old" Instruments. Where did you get the old version?

  • @Bobbias
    @Bobbias Месяц назад +1

    It makes perfect sense that avoiding the contains() should make best and worst case closer in speed.
    Unless I'm mistaken checking every flag would be O(nm) where n is the number of flags on the Regex and m is the number of flags to check against. Turning the flags into a bitmask would flatten this into O(m) since checking the bitmask is O(1) rather than contains() which is O(n).

  • @JamesGroom
    @JamesGroom Месяц назад +5

    Since there are only 8 flags, that means there are 256 possible string values, so can't you precompute those and use a LUT?

  • @msclrhd
    @msclrhd Месяц назад +8

    IIRC, both Mozilla and Google implement some of the JS functions in JavaScript.

    • @awesomekling
      @awesomekling  Месяц назад +8

      Yeah, WebKit as well. It does make a lot of sense :)

  • @Entarra
    @Entarra Месяц назад +13

    Curious to know if the c++ version could also cache its work and be faster still

    • @awesomekling
      @awesomekling  Месяц назад +19

      There’s definitely ways to achieve that, but then we’d lose out on the comfy vibes of writing JS in JS! 😎

    • @thislooksfun1
      @thislooksfun1 Месяц назад +2

      I was wondering that too! That seems like it would have a more profound impact to me, but maybe there's some limitation as to why that's not easy to do. I might spend some time this weekend messing around with it though.

    • @Entarra
      @Entarra Месяц назад

      @@awesomekling Hah, well then by all means :)

    • @colinstu
      @colinstu Месяц назад

      100% my thought too. Why not bring that caching to C++? But hey, if they're moving to swift, may as well rewrite it in that eventually once the limits of the JS engine have been reached. C++ can def move faster than JS - this is an implementation thing not a language thing.

  • @fritz1798
    @fritz1798 Месяц назад +1

    WHF! Very interesting and hackish, love it!

  • @berndeckenfels
    @berndeckenfels Месяц назад +1

    Are you constructing all those buildings objects in native or is there already some javascript shim code which gets installed in the runtime, then you can add the accessor there and don’t need extra parse runs (and also it can better optimize the whole call chain if the compiler sees all code on JS stack I imagine).

  • @janikarkkainen3904
    @janikarkkainen3904 Месяц назад +1

    I was anxiously waiting to see how much performance gain, if any, you could've gotten by removing the "silly jumps" from the bytecode emitter. It probably wouldn't be much, but still, they indeed were some "silly jumps".

  • @charleyramm1
    @charleyramm1 Месяц назад

    I enjoyed that very much!

  • @iSellEverything
    @iSellEverything 19 дней назад +1

    I'm sorry for the off topic comment, but what tool are you using to be able to drag a window from anywhere on a Mac?

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

      mmazzarolo.com/blog/2022-04-16-drag-window-by-clicking-anywhere-on-macos/

  • @halemm
    @halemm Месяц назад

    very intertesting seeing you using the debugger 😛

  • @markbauermeister5449
    @markbauermeister5449 Месяц назад +1

    When I wanna "cache" something in my C++ game engine I just write it to an unordered map and load it back from there later. Not sure how accepted that is as a solution, since I'm not the most proficient C++ dev.

  • @michal_havlicek
    @michal_havlicek Месяц назад +19

    Well Hello Andreas!

  • @fredleckie5880
    @fredleckie5880 Месяц назад +1

    Huzzah! A Stag beetle and a Scarab beetle?

  • @perotubinger
    @perotubinger Месяц назад +5

    I might totally missed this, but why couldn't you just use the flags substring and return that? And after you extracted the flags to a bit mask, couldn't you use that to make the native C++ accessor faster?

    • @msclrhd
      @msclrhd Месяц назад +3

      The JavaScript spec specifies a flag order so if you say /foo/gi or /foo/ig then flags will return the same value in both cases. This is useful for checking in JS if two RegExp objects have the same flags, etc.

    • @cxboog
      @cxboog Месяц назад +3

      Because javascript is optimisation's worst enemy; that behaviour is required by the spec (also) because the user is allowed to subclass RegExp and override...almost everything, even the pattern string itself.

    • @nordern1
      @nordern1 Месяц назад +1

      @@cxboog True, but it's fairly safe to assume that, most of the time, it will be invoked on a native RegEx object without overrides. Maybe there could be a fast path in that case?

    • @perotubinger
      @perotubinger Месяц назад

      @@msclrhd ah, makes sense. That's what I meant by "I might have totally missed this" :)

    • @cxboog
      @cxboog Месяц назад

      @@nordern1 yeah there's tons of these optimisation opportunities!

  • @charlieking7600
    @charlieking7600 Месяц назад

    You can use JavaScript to write more powerful compiler, so, technically, it's possible.
    But it would be practically hard, because GCC and Clang are leaders backed by professionals.

  • @twonkel
    @twonkel Месяц назад

    So glad you're doing videos again. Very inspirational!

  • @pigalex
    @pigalex Месяц назад +9

    here's another crazy idea you might consider: rewrite the UI (e.g the address bar area) in HTML. that would reduce dependence on Qt and would help with porting (could also make a desktop/tablet HTML UI and a mobile/vertical UI)

    • @spiritofstar
      @spiritofstar Месяц назад +1

      Yes, Firefox and Edge do it and they are relatively successful

    • @mariocamspam72
      @mariocamspam72 Месяц назад +1

      ​@spiritofstar Firefox uses a home-grown UI framework which describes layouts with XML

    • @spiritofstar
      @spiritofstar Месяц назад

      @@mariocamspam72 edge also uses React framework to build UI elements but that does not change fact that UI is built with web standards such as html or in Mozilla Firefox case XUL/xhtml

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

      @@mariocamspam72 edge uses react to build it’s UI,they are still web based UI, what is your point?

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

      @spiritofstar Firefox's UI framework is fully native, that's my point 😁. You're comparing two different things.

  • @Sosisoos
    @Sosisoos Месяц назад +17

    Sorry for the off-topic question, but do you see yourself returning to Serenity sometime?

    • @awesomekling
      @awesomekling  Месяц назад +55

      Not anytime soon. I have a browser to build!

    • @Oarix24
      @Oarix24 Месяц назад +1

      @@awesomekling❤

  • @lypanov
    @lypanov 26 дней назад

    Maybe a silly question. Can the original get() that you wanted to optimize reuse inline caches somehow? By running in the JS context it was called from vs running from the perspective of C++ attempting to access JS context? So kind of a JS -> JS trampoline by way of the C++? Obviously something no JIT can do... but if you're sticking to interpreter land anyway... why not?

    • @lypanov
      @lypanov 26 дней назад

      The PIC would need to be associated with the C++ itself. Maybe some sort of upfront declaration in the C++ as to what might be accessed.

  • @jeffalonet
    @jeffalonet Месяц назад

    just curious, in macos, how are you dragging the window from anywhere?

    • @awesomekling
      @awesomekling  Месяц назад +1

      mmazzarolo.com/blog/2022-04-16-drag-window-by-clicking-anywhere-on-macos/

  • @Siminfrance
    @Siminfrance Месяц назад +2

    Wouldn't optimising the c++ code be more beneficial in the long run?

    • @lypanov
      @lypanov 26 дней назад

      In a future of never JIT yes, in a future of JIT, no.

  • @FredClausen
    @FredClausen Месяц назад +15

    WHF!

  • @BrazilMentionedHueHue
    @BrazilMentionedHueHue Месяц назад +4

    How has been your experience with copilot so far?

    • @awesomekling
      @awesomekling  Месяц назад +11

      Love it! Don’t think I’ll ever go back to programming without LLM autocomplete. So much less friction, especially when doing less interesting tasks. :)

    • @XeZrunner
      @XeZrunner Месяц назад +2

      It makes so much more sense to use LLMs as autocomplete helpers instead of fully writing entire files/classes/functions with them. After all, they're basically super good word/token predictors behind the curtains.

    • @colinstu
      @colinstu Месяц назад

      @@awesomekling hope you have an interview / talk with ThePrimeagen some day, know you two had a small interaction already. He's had an interesting time with Copilot, hope that topic comes up during the talk.

  • @Tabonx_
    @Tabonx_ Месяц назад +2

    Where would I even start to learn this kind of wizardry? As an iOS dev, it all feels so foreign. I barely touch the terminal, and mixing languages, especially the way you did here, seems impossible to me.

    • @awesomekling
      @awesomekling  Месяц назад +13

      Try doing new things just outside your comfort zone every week :)

    • @ferdynandkiepski5026
      @ferdynandkiepski5026 Месяц назад +2

      And touching the terminal is quite useful. You could see how he forced himself away from lldb.

  • @Derrickasaur
    @Derrickasaur Месяц назад +15

    Swift vs Rust solved = just use JavaScript

  • @dennisheij8793
    @dennisheij8793 Месяц назад

    Couldn't you use the flags enum to create the flags string from C++?

  • @ChillerDragon
    @ChillerDragon Месяц назад

    Catchy title hehe

  • @aiuno
    @aiuno Месяц назад

    Hey! Haven't watched in a bit. When/why did you switch to Mac?

    • @TheRealFallingFist
      @TheRealFallingFist Месяц назад

      I believe he was always on Mac, running SerenityOS in a VM. But he's put creating Serenity on hold, since he's focusing on the Ladybird browser exclusively right now.

    • @TBasianeyes
      @TBasianeyes Месяц назад +1

      @@TheRealFallingFist Nah, he worked on Ubuntu for years. The latest Macs just compile so much faster than anything else so why wouldn't you use that.

    • @yeppiidev
      @yeppiidev Месяц назад

      ​@@TBasianeyes Also, he's an ex-apple employee. So I think he's also very comfortable with Macs

  • @raajroy5931
    @raajroy5931 Месяц назад +1

    I would really appreciate it if somebody tells me the *font face* kling is using

    • @awesomekling
      @awesomekling  Месяц назад +1

      It's in the video description :)
      Berkeley Mono: berkeleygraphics.com/typefaces/berkeley-mono/

  • @doyouwantsli9680
    @doyouwantsli9680 Месяц назад

    Js with good usage of sqlite is faster than c++ with poor usage of a db (especially a more bloated one)

  • @ferdynandkiepski5026
    @ferdynandkiepski5026 Месяц назад

    Would the length of the regexp have an impact on the speed? I could see this being where JS gets slower. Your regexp was very short and quite sane. What people create with regexp isn't sane.

    • @awesomekling
      @awesomekling  Месяц назад +2

      The regular expression itself will still be evaluated by the same C++ regex engine we have. We're not implementing a regex engine in JS :)

  • @asphexor
    @asphexor Месяц назад

    This is mad hacking video!

  • @SachinDolta
    @SachinDolta Месяц назад

    Good one

  • @alexander3293
    @alexander3293 Месяц назад

    Doesn't V8 even have a "custom language" to do this?

  • @aetube
    @aetube Месяц назад

    Well that's debatable

  • @deckard5pegasus673
    @deckard5pegasus673 Месяц назад +15

    I only watched until 7:00 but as soon as you said it was a problem with C not caching previous gets, I stopped the video. In those cases I do something similar this, and problem solved. I have a bit field to see if the get has been previously called, and another bit field to for the boolean get values. This is "old republic" C, if you don't like bit fields and bit manipulation, just use an array of booleans, or whatever, although it's less memory efficient. Maybe I should have watch the entire video, because maybe this isn't what you are looking for, but I didn't have time for an hour video today.
    bool getFlag(RegExpObject* regexp, const String& flagName)
    {
    static char FlagNames[][16] = { "global","ingoreCase", "multiline", "sticky", };
    static int numFlags = sizeof(FlagNames) / sizeof(FlagNames[0]);
    static int RegExpFlags = 0 , RegExpCached = 0;
    for(int i=0; i> i) & 1))
    { RegExpCached |= (1 get(flagName)))
    RegExpFlags |= (1 > i) & 1);
    }
    }
    printf("error not found");
    return false;
    }

    • @Bobbias
      @Bobbias Месяц назад

      Maybe you should have paid a bit more attention to what he was saying before you stopped the video, because it wasn't that the flags themself aren't cached.
      The issue is that a property access requires walking the prototype chain to find where the property actually exists, and in C++ there is no cache in the property lookup function, so they're forced to walk that chain every time. JS caches that part of the property lookup process.
      He also did use a bitfield to hold the actual flags because he discovered that the flags were being stored as a string and each lookup was calling contains() to search for each letter, but that was after moving to JS to take advantage of the property lookup caching.

    • @deckard5pegasus673
      @deckard5pegasus673 Месяц назад +9

      I believe I have understood the issue. The first call to regexp.get in any language requires walking the prototype chain to find the property. Javascript uses automatic inline caching to speed up subsequential calls to each property.
      My C function implements a similar caching mechanism using a 32-bit bitfield. This can be even faster because the bitfield fits easily within the CPU cache, whereas JavaScript's inline caching, although fast, depends on various factors, including the JavaScript engine's implementation and may not always fit in the CPU cache
      Where I think there might be confusion is that both C and JavaScript must walk the prototype chain for the first call. The real key advantage of implementing this in JavaScript is the reduced overhead from cross-language context switches, which can be significant, but this does not avoid the initial property lookup. Writing this logic in JavaScript doesn’t eliminate the overhead of the initial call; it merely optimizes subsequent accesses, which my C function also does.

  • @Awwe12675
    @Awwe12675 Месяц назад

    JavaScript is scripting language implemented by C++ we can’t run JavaScript without C++

  • @GodlyBuTcheR
    @GodlyBuTcheR Месяц назад

    Well Hello!

  • @theRealSPACEDANCE
    @theRealSPACEDANCE Месяц назад

    Very cool video, thanks! Question: Why CLion over Qt Creator? As a new Qt Oslo Office employee to an old one :)

    • @yeppiidev
      @yeppiidev Месяц назад

      Maybe because he wants to try new stuff :^) He used to use Qt creator back in the Serenity days before the idea of Ladybird was conceived

  • @ericdanielski4802
    @ericdanielski4802 Месяц назад +1

    Nice video.

  • @underflowexception
    @underflowexception Месяц назад +1

    TIL: vim !$

    • @ankk98
      @ankk98 Месяц назад +1

      !$ in bash refers to the last argument of the previous command. It's a quick way to reference and reuse the last parameter from your previous command.

  • @TobyAsE120
    @TobyAsE120 Месяц назад

    whk! js hacking, very fun!

  • @nopair5688
    @nopair5688 Месяц назад

    no way ?

  • @inukonet
    @inukonet Месяц назад

    Why not just return the inner flags string?

    • @inukonet
      @inukonet Месяц назад

      Ah the flags property has a defined order and the input flags param can be in any order. Hm bizarre, returning the u32 flags to cpp should be faster still.
      Anyways, i like the idea od pushing stuff to js, as that makes you “dogfood” your js runtime and thus have (another) reason to make it fast.

    • @awesomekling
      @awesomekling  Месяц назад +1

      JavaScript is very dynamic. Someone could replace the original flag getters on a RegExp object with their own, and then we have to invoke those getters, which may lead to arbitrary behavior and side effects.. it's a fun language!

    • @inukonet
      @inukonet Месяц назад

      @@awesomekling haha you are right, I guess the workaround for that would be worse that the original code. Fun indeed :D

  • @TheHanutaXD
    @TheHanutaXD Месяц назад

    Wait, why does this video have so many dislikes?
    At least RYD thinks it is disliked :/

    • @awesomekling
      @awesomekling  Месяц назад +5

      This video currently has zero dislikes. Your extension is just showing you a random number :)

    • @TheHanutaXD
      @TheHanutaXD Месяц назад

      @@awesomeklinggood to hear :) seems like it is 50/50ing for some reason

    • @colinstu
      @colinstu Месяц назад

      @@awesomekling The extension has a separate backend/DB for users of the extension, so other extension users who downvote have it all kept track there and that number is returned.

    • @colinstu
      @colinstu Месяц назад

      Because javascript stinks probably.

    • @Akrob55555
      @Akrob55555 Месяц назад

      Those extensions do not work. They just make stuff up. Stop using them.

  • @my_name_is_ahad
    @my_name_is_ahad Месяц назад

    I like your desktop wallpaper.

  • @Oarix24
    @Oarix24 Месяц назад +2

    MORE OF
    SerenityOS PLZ

  • @glenfordwilliams5716
    @glenfordwilliams5716 Месяц назад +1

    WHF!