E03: C# vs Java: Which is Faster? Computer Language Drag Racing Series

Поділитися
Вставка
  • Опубліковано 14 жов 2024
  • Which language produces the fast apps? How do C# and Java Compare? How are bytecodes and IL different?
    Dave takes you on a tour of C# and Java and then drag races them by running them through their paces with a prime number generation benchmark in Episode 03 of the epic Computer Language Drag Racing Series episode 03. This series tests more than 60 languages by having the same goal in each language - solve all the primes under one million as many times per second as possible.
    Languages tested in the series include ARM ASM, X86 ASM, Ada, BASIC, Bash, C, C++, C#, D, Dart, Delphi, F#, Fortran, Go, Haskel, Java, Julia, Lisp, Lua, Node, Nim, OCaml, Octave, PHP, Pascal, Perl, Powershell, Python, R, Ruby, Rust, Scala, SQL, Swift, TypeScript, V, Zig, and more are being added!
    Each round, languages are tested in groups, such as C vs C++ vs Rust, Python vs BASIC, Ada vs Pascal vs Delphi, and so on.
    Github Code: github.com/Plu...
    The Shirt (static blue): amzn.to/2VnFuzF
    Episode List:
    E00: • E00: Software Drag Rac...
    E01: • E01: What is the FASTE...

КОМЕНТАРІ • 1 тис.

  • @kirkeasterson3019
    @kirkeasterson3019 3 роки тому +256

    Name suggestion: Fizzbuzz Aldrin

  • @PhilipStorry
    @PhilipStorry 3 роки тому +746

    The Stig was named after a character from a children's book - "Stig of the Dump".
    So the only choice for our new friend's name must surely be "Stack", or to give him his full name "Stack of the Dump". 😉

    • @igorthelight
      @igorthelight 3 роки тому +19

      +1 for Stack

    • @excitedbox5705
      @excitedbox5705 3 роки тому +20

      Stack Dump. I like it.

    • @DavesGarage
      @DavesGarage  3 роки тому +204

      I like it... but rather than just "Stack", maybe he should be "The Stack" to stay orthogonal with "The Stig"? Does it matter?

    • @PhilipStorry
      @PhilipStorry 3 роки тому +45

      @@DavesGarage That's a very fair point, The Stack is better. Feel free to use that if you prefer it! :-)

    • @Damaniel3
      @Damaniel3 3 роки тому +5

      Perfect.

  • @Midnotion
    @Midnotion 3 роки тому +479

    Java runtimes have been doing JIT for ages now, and are even smart enough to only spend time optimizing frequently-executed code, eliminating the overhead of compiling the full thing.

    • @neil2444
      @neil2444 3 роки тому +35

      With some tweaking, I've seen Java be competitive with C++. Of course you have to disable garbage collection..

    • @sysosmaster
      @sysosmaster 3 роки тому +33

      @@neil2444 you mean “take controle of the Garbage Collection”, the GC is not in your way of you tell it when to work…. Instead of letting it run at its own schedule.

    • @framegrace1
      @framegrace1 3 роки тому +18

      Also, there are other languages that compile in java byte code, even functional ones like scala. And at the beginning, java byte code had to had a hardware CPU implementation called picojava. I've seen the Fujitsu implementation running and was very cool.
      Few people remembers that java origins were to be a language for microcontrolers, like micropython is today. The bytecode idea was to be able run on java native microcontrolers, or be compiled to any other microcontroler easily.

    • @neil2444
      @neil2444 3 роки тому +9

      @@sysosmaster The algorithm itself for the GC is way more taxing than simply deallocating the allocated memory like you would in C++. I don't recall what they did exactly, but I think it involved launching garbage collection after memory was freed, and even then, only at the end. When you think about it, deallocation of memory is O(1) in C++.

    • @sysosmaster
      @sysosmaster 3 роки тому +4

      @@neil2444 Well. You do more than just deallocating if you use a GC, also depending on how configure your compiler, your reallocation might even not run when you expect it to… or at all….

  • @KennethSorling
    @KennethSorling 3 роки тому +221

    Suggested name for the Baby Stig: Intern Inside

    • @MagnoLima
      @MagnoLima 3 роки тому +1

      I really like that! lol ... Intern Inside

    • @dviljoen
      @dviljoen 3 роки тому +1

      This comment wins the internet today.

    • @priyeolise
      @priyeolise 3 роки тому

      I love it

    • @Aquineas
      @Aquineas 3 роки тому

      I̶n̶t̶e̶r̶n̶ Millennial Inside (FTFY!!)

    • @DarthFader3000
      @DarthFader3000 3 роки тому

      Eltin

  • @georgesealy4706
    @georgesealy4706 3 роки тому +103

    I would just like to add that as a contractor engineer I wrote lots of code in both C# and Java. When you go into a situation, most of the time you don't have a choice. A company has its infrastructure, and that is that. So, it's good to learn both, even at home in your 'off time.' Then you can enhance your resume and have more job security.

    • @ryan-el9er
      @ryan-el9er 3 роки тому +4

      I’ve been a hobbyist programmer since 2005 (spanning many, many languages) and I am proficient in C#. for some reason, I’ve gone all these years and never obtained experience with Java. I have no intention to work for anyone else and I am curious if you personally enjoy using Java more than C#.

    • @georgesealy4706
      @georgesealy4706 3 роки тому +12

      @@ryan-el9er I didn't enjoy one more than the other. The thing I liked about Java was that I could do my work in a Windows development environment and then deploy the code to a Unix/Linux server. That was cool. A number of applications from IBM or Oracle ran on Unix and there was a need to extend them in some manner. Those applications incorporated a JRE, so it was necessary to write the additional code in Java. If you are not working for someone other than yourself or not working with a Unix/Linux server, then you probably don't have to worry about Java. There are some web servers that run on Windows that use Java, such as JRun. So you might run into that situation.

  • @izzieb
    @izzieb 3 роки тому +226

    The trailer needs more echo and fire.

    • @masmullin
      @masmullin 3 роки тому +2

      To be honest, I coulda used a little more cowbell.

    • @joho0
      @joho0 3 роки тому +1

      He borrowed it from a well known spoof. I'd post the link, but my comment will be removed. Just Google Sunday Monster Truck and click the first link.

    • @UncleUncleRj
      @UncleUncleRj 3 роки тому

      @@joho0 I remember those commercials.... not that one specifically on Google but the "SUNDAY! SUNDAY! SUNDAY!" monster truck commercials were great and very well known... I think I even saw one as near as 3 or 4 years ago for Monster Jam.

  • @MeriaDuck
    @MeriaDuck 3 роки тому +41

    For Java, there are multiple runtimes to choose from. Ibm, Azul, Graal by Oracle, openjdk,... So even the same code can run a bit differently between those.

    • @SodexGames
      @SodexGames 2 роки тому +3

      Would love to see it in Graal native image

  • @silencioseu
    @silencioseu 3 роки тому +157

    7:39 JVM bytecode is indeed jitted, and there's also the HotSpot AOT optimizations.

    • @JohnDavidDunlap
      @JohnDavidDunlap 3 роки тому +16

      I was thinking the same thing. If memory serves, Java has had a JIT since the late 90's or early 2000's.

    • @DavesGarage
      @DavesGarage  3 роки тому +34

      I still can't find Oracle-sourced info saying, though I implied it HAD to be true at that speed; anything in the JDK docs that show that it JITs to machine code? I believe you but could not find official proof!

    • @theosib
      @theosib 3 роки тому +32

      @@DavesGarage I have previously configured the JVM to log the compiling it does so that I could see the x86 code dynamically generated. For blocks of code, it interprets for a while then does a fast compile to run that for a while and then finally aggressively compiles.

    • @Salzui
      @Salzui 3 роки тому +2

      @@CurtCox Stuff like -g for debug information into the generated jvm bytecode should be nearly irrelevant, it will just unnoticeably increase loading times, the jvm jit can just ignore that. -target will only check/allow/deny usage of stuff added to the standard library later on, the bytecode did not improve or change really between java 8 and 16.

    • @gattagattag
      @gattagattag 3 роки тому +6

      @@DavesGarage The HotSpot VM (released in 99) has been the default runtime for Java since 1.3. Its core feature being just in time compilation. It features a multi-tiered approach to JIT that is significantly more involved than the .NET Runtime. Nowadays GraalVM is of most interest in the JVM runtime world, as it is implemented in java itself and can optimize all aspects of itself (This is not really why it's so revolutionary, but it's very relevant to the JIT conversation). It has many other very analyzes it can perform, but you should read up on it. You should really try to run your benchmark again with GraalVM instead of hotspot, if you were using Java 11 it's already included in your distribution but not enabled.
      Edit: I forgot about this, but one note about Graal is that, unlike C2, it does not support auto vectorization, and while I have not do not remember what the primes impl you used looks like, I would not be entirely surprised if auto vectorization was performed. Though on the note of vectorization, Project Panama did bring us JEP 414, which adds the ability to describe certain SIMD workloads and have those executed in platform specific hardware

  • @breckohlson7410
    @breckohlson7410 3 роки тому +8

    Fast becoming one of my primary tech channels. Thank you for the work and information you pack into each vid. Your blooper real at the end reminds me of writing code, compile error, fix, write more, compile error, fix, rinse repeat lol...great stuff.

  • @berinloritsch
    @berinloritsch 3 роки тому +12

    NOTE: Java is runtime compiled, so not necessarily just interpreted. The major distinction between C# and Java is _when_ this compilation happens. Java also has/had hot spot compiling where further optimizations could happen.

    • @millfreedom
      @millfreedom Рік тому

      And that’s exactly the reason, why Java code should be “warmed up” before testing its real performance: it might show dramatic increase after some methods will be decided “hot” and the optimizations like “inlining” will be applied.

  • @ViorelMocanu
    @ViorelMocanu 3 роки тому +6

    Massive respect for the continuous steam of super valuable, in-depth information you constantly churn out during each of your videos! Kudos and keep up the great work, Dave!

  • @burtonrodman
    @burtonrodman 3 роки тому +63

    i have to take objection to your description of IDisposable. it does not immediately GC anything… it’s just an opportunity to manually release unmanaged resources. all other GC and reference rules still apply to the remaining managed objects

    • @SimonBuchanNz
      @SimonBuchanNz 3 роки тому +2

      With the extra complexity of tracking if the finalization has run or not!

    • @burtonrodman
      @burtonrodman 3 роки тому +1

      @@SimonBuchanNz technically it’s tracking if dispose has been called or not so that finalize can be suppressed as an object with a pending finalizer is disqualified from gen0, but point taken

    • @SimonBuchanNz
      @SimonBuchanNz 3 роки тому

      @@burtonrodman blarg, too long since I've dealt with C# I guess.

    • @RuiPalmeira
      @RuiPalmeira 3 роки тому

      This. Easy to notice it if you take a look at the resources graph that VStudio provides ( if there's a GC "pass" it will show in the memory graph , and even when you run an IDisposible() method, it will not GC "on demand" ).

    • @knm080xg12r6j991jhgt
      @knm080xg12r6j991jhgt 3 роки тому

      Doesn't Java's try-with-resources construct do something very similar?

  • @booganaga123
    @booganaga123 3 роки тому +152

    I'd love to see the system languages! Rust vs. C vs. C++ etc.

    • @tiarkrezar
      @tiarkrezar 3 роки тому +11

      It'd be nice to squeeze D and Zig in there too. Would that be too much for one episode?

    • @skyletoft
      @skyletoft 3 роки тому +10

      ​@@tiarkrezar Isn't D garbage collected? Or is that optional?
      (And on that note, according to the library standard, so is C++, it's just that none of the major implementations ever implemented the GC)

    • @tiarkrezar
      @tiarkrezar 3 роки тому +7

      ​@@skyletoft from what I understand, it allows you to use both manual memory management and GC.
      That said, maybe you could put D in a group with Swift and Go, that'd be an interesting comparison too.

    • @dra6o0n
      @dra6o0n 3 роки тому +1

      Rust is evolving at a steady pace, Microsoft and other tech corporates are kinda interested in it for the security and performance.

    • @Caesim9
      @Caesim9 3 роки тому +7

      I think Rust is closer to C++ and think that episode should be C++ vs Rust and Zig is closer to C so their episode should be C vs Zig.
      D belongs either in the C++ and Rust bucket or would be better in a D vs Go episode'

  • @robertfrappier699
    @robertfrappier699 3 роки тому +14

    IDisposable does not reclaim the memory. It's only used to free resources that you don't need anymore like a file or socket connection.

  • @mcneilm76
    @mcneilm76 3 роки тому +3

    These videos just plain rock!!!! Awesome work and ultimate kudos Dave!!!! (It’s probably worth mentioning that I’ve seen 1000’s of youtube videos and this is probably the third I’ve ever felt compelled to comment on!)

  • @VeauX1902
    @VeauX1902 3 роки тому +51

    “The Stieve” could work as a name

  • @TheBadassTonberry
    @TheBadassTonberry 3 роки тому +14

    I mainly program in C#, but I genuinely *enjoyed* working with Java. say what you want about Oracle, but they definitely know how to develop "ergonomic" (for the lack of a better word) products.
    That being said, I'd go with C# here.

    • @raianmr2843
      @raianmr2843 2 роки тому

      You're crediting the wrong company here. Java's legacy of being a dumb refuge for inexperienced C++ people goes back to Sun days.

    • @RetroDawn
      @RetroDawn 2 роки тому +6

      That is because Sun invented Java and shepherded it for going on 2 decades before Oracle finished their acquisition of Sun. And Oracle didn't purge the Java team (although some left, most notably Gosling himself), and a VT-based Sun veteran leads the Java architecture to this day.

  • @DanknDerpyGamer
    @DanknDerpyGamer 3 роки тому +6

    C# is one of my favorite languages and IMO you articulated (even if briefly), at various points, aspects about the syntactical & technical sides of C# that I love far better than I could when talking with friends about C# haha.

  • @JheregJAB
    @JheregJAB 2 роки тому +8

    This is a cool series! I'm a bit disappointed that it seems to only have a few episodes in it, I was really enjoying the language tutorial / discussion followed by the results.

    • @pelomojado3535
      @pelomojado3535 Рік тому

      Thats probably cause sone people got salty of their fav languaje being slow, a shame really

  • @limitationsapply
    @limitationsapply 3 роки тому +35

    10:00 - A classic error here is the use of system time to measure elapsed time. This is a mistake because system time can be changed arbitrarily during execution by network time services or by the user - it can even go backwards.
    The solution is briefly mentioned at 16:00 - the Stopwatch class. You mention it's more ergonomic, but more importantly it's *monotonic* - it never goes backwards, and it isn't effected by changes to the system clock.
    Other languages offer similar mechanisms: Java's System.nanoTime, Rust's std::time::Instant, C++'s std::chrono::steady_clock, Ruby's Process.clock_gettime(Process::CLOCK_MONOTONIC), Python's time.monotonic.

  • @artist6000ish
    @artist6000ish 3 роки тому +21

    Dave, I think you're confused about the use of the using clause. In the example you stated, using a using clause won't have the effect that you describe. The memory that the garbage collector is hanging on to will still stick around. All that the using clause does is call the Dispose method at the end of the block, and will do so even if there's an exception. You could simulate it using a try/finally. In fact, that's all that the using clause does -- constructs a try/finally for you behind the scenes.
    It's useful when you want to do something at the end of a block that's deterministic. For instance, let's say that you want to start a stopwatch at the start of a block, and stop it at the end. You can construct an object that does just that: start in the constructor and stop in the Dispose() method which gets called for you automatically. It's also useful, and necessary, as a way to release unmanaged memory, or "free" any other resource that's scarce such as file, sockets, etc.
    But if you want to actually free memory, you have to ensure there's nothing dangling by setting variables to null, and then call GC.Collect. There's folk-lore out there on calling Collect multiple times to "really really" collect. It's not deterministic, and technically the GC can ignore your Collect call, and do it later if it wants.

    • @todortodorov940
      @todortodorov940 2 роки тому

      Correct. The *IDisposable* is only useful for unmanaged resources (non .Net memory, file handles, etc.), other clean-up operations and some programming patterns. There is NO WAY you can tell the GC to free memory. The GC does this when it decides it is the correct time to do this.
      Than said, you can force a Garbage Collection, an operation which is expensive and by forcing it, you are probably picking not the optimal time to do this. If you can, you can design your types to be stack allocated (called "value types" or structs), which does not need GC, but this has some limitations. For an advanced scenarios, and this may work in Dave's sieve alg., a reference type object can be stack allocated - but you lose the protections provided by the CLR.
      And to be honest, a good GC alg. will say: "I see you are doing performing some heavy computations. As there is still plenty of free memory, I will wait reclaiming memory until things cool down.". In other words, the GC should not affect Dave's tests. And if you want to test the alg. alone, just re-write the tests and reuse the memory.

  • @programorprogrammed
    @programorprogrammed 3 роки тому +19

    The extra time spent discussing the languages really adds to this series. Thanks Dave!

  • @MNGoldenEagle
    @MNGoldenEagle 2 роки тому +6

    Another thing worth noting is that C# does offer the capability to compile natively (foregoing the IL and JIT, at the expense of losing reflection and some other features). Java has explored this capability, but I don't think it exists in the latest version. This could have performance impacts as well and might be interesting to explore comparison-wise.

    • @runninggames771
      @runninggames771 Рік тому

      What is this feature called? Im un aware of any way of doing this outside of unity’s IL2CPP

    • @radiosification
      @radiosification Рік тому

      @@runninggames771 It's called Native AOT

    • @AryzenI
      @AryzenI Рік тому

      ​@@runninggames771 NativeAOT, I think

  • @crispoman
    @crispoman 3 роки тому +15

    Some say he's a piece of dummy code put in to allow a program to run. Some say he's probably not going to get rewritten properly. All we know is: he's called The Stub.

    • @maighstir3003
      @maighstir3003 3 роки тому

      Now I'm torn. I saw The Stack first, but with that intro, I'm leaning towards The Stub.

    • @paulfalke6227
      @paulfalke6227 3 роки тому

      The point of view of a BOFH: applications are stubs to make the system load display more interesting. Yes, call the little Intel man "Stub", as nickname for Stubborn!

  • @rando5673
    @rando5673 2 роки тому +4

    I'm not even a programmer, I've only ever written the most basic of code. But even I get the feeling this guy has some extremely deep knowledge and find it fascinating to watch

  • @roycsinclair
    @roycsinclair 3 роки тому +5

    For a whiteboard grid use Vis-a-Vis markers as you'll remember teachers used with their overhead projectors for the lines, labels etc. That way you have lines that don't erase by accident when trying to update grid contents but when you're done you can wash away with nothing more than a damp cloth.
    Nothing to do with programming but a useful tidbit to know.

  • @aztracker1
    @aztracker1 3 роки тому +24

    Been thinking it would be interesting to take a wasm target build and test the different web assembly runtimes in a similar way.

    • @AXYZE
      @AXYZE 3 роки тому +1

      Would love to see that!

    • @johnernest8109
      @johnernest8109 3 роки тому +2

      Took that down to 10000000 iterations 7 zeroes instead of 8 to be nice so that Java wouldn't actually crash with the GC overhead limit error.
      New Results:
      C++: 617ms
      C#: 1285ms
      Java: 5035ms
      Yep, that definitely sounds more like real world scenarios I've had with each.

  • @kozmizm
    @kozmizm 2 роки тому +1

    According to what I've read and what I understand, back from the days of Java 8 JVM JIT, some of the Java byte-code is turned into raw machine code using the JIT compiler. The interpreter is able to analyze which code is most likely to be used the most, like loops, and it converts it into machine code so that it executes faster. They were also working diligently on adding more and more stuff that will convert into compiled code. Somehow it is able to do this and use a hybrid of byte-code plus machine code running together, passing information between compiled and bytecode with almost no performance loss, in order to make java extremely fast and competitive with compiled languages.

  • @Dooobs
    @Dooobs 3 роки тому +45

    Ministig can be called OptimalPrime, because reasons 😄

  • @neoncyber2001
    @neoncyber2001 3 роки тому +6

    I'm not that surprised that Java won this one. The Java Awt 2D API is amazingly fast . Java has been around for as long or longer than any other managed language, and much of that time has been used optimizing the living crap out of the jvm and javac.

  • @luisfranciscordg
    @luisfranciscordg 2 роки тому +3

    I'm a .NET dev, haven't used Java since 2002.
    I think you should specify which version of .NET you are running your tests, there is massive difference is speed between .NET Framework 1 vs .NET 6.
    And the same I think could apply to the JVM you're using.

    • @Quique-sz4uj
      @Quique-sz4uj 2 роки тому

      Yeah we should see this with .NET 6. Also the attribute he uses to heavily optimize the code in C# is probably hurting performance in this case.

  • @doctor.davinci.76
    @doctor.davinci.76 3 роки тому +25

    For a second there I was expecting Jay's face from Jay's Two Cents to appear and for him to start doing one of his iFixit ads

  • @gwaptiva
    @gwaptiva 3 роки тому +12

    The unclearest part of the Java code to a Java programmer is the formatting :D

    • @Brahvim
      @Brahvim Рік тому

      Is it because it uses Allman braces? Ahahaha!

  • @mensfeld
    @mensfeld 3 роки тому +2

    Maybe one interesting point regarding Java JIT vs native compilation. There are ways to compile Java code directly into native code via GraalVM. I compared the codes in some benchmarks similar to this one. The most interesting part is, that the native code is not at all faster, like the interpreted (and probably heavily JIT-ed code). The only parts the native version performs better is the startup time and memory consumption. But in raw computation power, not at all.

  • @michaelday6987
    @michaelday6987 3 роки тому +11

    C# is and probably always be my language of choice. I am scarred by my experience with Java in college.

  • @David-id6jw
    @David-id6jw 3 роки тому +2

    Which version of the bool array did you use for C#? Probably the default version in solution_1? There are three variants on the bool array in solution_1. On my machine (using docker, to match your run), they return scores of 2601 for bool, 3026 for ibool, and 8362 for dbool. Except...
    I just realized (from a comment you made in the video) there was an optimization I missed in the bool code. Fixing that, the bool version increases from 2601 to 6168, and the ibool version increases from 3026 to 8824. Yes, a stupid speed bump on the hot path slowed things down that much.
    I'm going to have to update that in the repo. Hopefully you can double-check it before your next video.
    *Note: the bool version treats the array values exactly like the bitarray version (0 = non-prime, 1 = prime). The ibool inverts the logic so that you don't have to initialize the array twice (since the runtime initializes the array to 0, while the default algorithm requires the sieve to initialize all the array values to 1). Thus the ibool version is a decent bit faster.

  • @mullergyula4174
    @mullergyula4174 3 роки тому +15

    Once I ported a piece of complex java code to C and had to work hard for days to get near to the speed of the Java version. JVM's JIT is pretty good. You can beat java in C or even more in assembly if you can design you code to use vector instructions. How often do you need that? You can always do this for the most critical part of the code for most languages.

    • @c0deventures
      @c0deventures 3 роки тому +2

      Nothing beats the speed of compiled code. This is a fact and nothing can change that. This proves that your porting of the code hadn't been efficient.

    • @mullergyula4174
      @mullergyula4174 3 роки тому

      @@c0deventures LOL

    • @adambickford8720
      @adambickford8720 3 роки тому +2

      @@c0deventures Good thing Java is JIT compiled!

    • @jhoughjr1
      @jhoughjr1 3 роки тому

      trying to port a pattern from an interpreted lang to a compiled lang isn't equivalent.
      It is literally physics.

  • @Scoopta
    @Scoopta 3 роки тому +1

    Java has been doing JIT basically since the beginning. The first JIT engines were implemented in Java 1.1(3rd party JVM) and 1.2(Sun's official JVM) which were released in 1997 and 1998 respectively. In fact if you run your JVM with -Xint, this disables the JIT engine and forces true interpretation as you suggest, you'll see the massive performance benefit the JIT engine brings. In fact not only does the JVM have a JIT engine it's often considered to be faster and better optimizing than the one in .NET.

  • @MartijndeBoer
    @MartijndeBoer 3 роки тому +9

    Featuring the haxe version would be cool, it is a language that needs more love from the world 😊😍

  • @jsteezy80
    @jsteezy80 2 роки тому

    Growing up my step dad worked for intel and somewhere I have some of those Intel bunny suit character that you were showing. Like you said huge advert back in 1991 when they started "Intel Inside" promo. If I can find them I can send you a few. I think I have 10 or so, 2 of each color. Anyway, brought back memories. Keep up the good work

  • @tokiomutex4148
    @tokiomutex4148 3 роки тому +15

    20:26 the JVM has a JIT compiler

  • @kozmizm
    @kozmizm 2 роки тому +1

    according to the Java 8 JVM specification, all data types are actually stored in RAM using 4 bytes or 2 * 4 bytes in memory if they are 64-bit data types, even they are a bool, a short, and even a byte. Yes, it seems crazy that a byte data type takes up 4 bytes in memory, but that's probably because it reduces the complexity and number of op codes(there are only 256 op codes, as far as I can recall in Java 8). The only exception was, like you said, there is a boolean array special data type that actually does it's best to store bools as bits within a segment of memory, to conserve space, but it has some overhead, and I think it is a special class and not a primitive. Anyhow my point is that Java does not store things as 8 bits or 16 bits, as far as everything up to Java 8 is concerned. it always stores them as 32 bits, aka 4 bytes, or 2 of those segments for 64 bits, even if most of those bytes are unused. I can't comment on anything past Java 8. I have only read the Java 7 and 8 language specifications and the JVM 7 and 8 specifications

  • @keganmillard1030
    @keganmillard1030 3 роки тому +69

    Dave needs graphs in his videos...

    • @dpapa2175
      @dpapa2175 3 роки тому +3

      leaderboard would be nice

  • @dunste123
    @dunste123 3 роки тому +2

    This give me so much insight in how java bytecode actually works, thank you

  • @tonywtyt
    @tonywtyt 2 роки тому +3

    I'm not a C# programmer, but I appreciated your explanation of the use of uses.

    • @Nusremmus
      @Nusremmus Рік тому

      If you know Java, you're one inch from knowing C#, which probably started as J++, until Microsoft got sued and lost. And I finally threw my J++ book away just last year :P

    • @calebvear7381
      @calebvear7381 Рік тому

      His explanation of the “using” statement was actually incorrect. It doesn’t free up memory or anything like that. All it does is ensures that the objects Dispose method is invoked when leaving the block.
      It is very useful for making sure you cleanup any resources you were using (eg close files, network sockets etc) but does not impact the garbage collection at all.

  • @fluffycritter
    @fluffycritter 2 роки тому +1

    Several others have pointed out that Java gets JITted in most modern stacks, but there's also a few examples of compilation from Java directly to machine code, such as by using gcj, which I've actually used in production code in very specific circumstances. (I do not recommend it if you can avoid it.)

  • @skyletoft
    @skyletoft 3 роки тому +11

    Since you haven't fixed the typo since last episode: Haskell has two Ls

  • @michaelpezzulo4413
    @michaelpezzulo4413 2 роки тому +1

    I learned more about programming in the first 13 minutes of this video then the first 4 weeks of class at college.

  • @theaninova
    @theaninova 3 роки тому +4

    Java vs Kotlin, Scala, Groovy, Clojure, etc (JVM languages)
    JS vs TS, Dart, CoffeeScript, Reason, Haxe, Nim, Kotlin etc (JS languages)
    x86 ASM vs C, C++, Rust, Zig, etc (Low-level languages)
    JVM Languages vs .NET Languages vs Node Languages (Typical Backend Languages), maybe also include Go, Ruby & Crystal
    And then functional and mixed functional languages, such as
    Haskell, F#, Scala, Reason, Kotlin

    • @grjj09
      @grjj09 3 роки тому

      Although Nim can compile to javascript (and c++ and objective-c), mainly the c-backend is used by people, so Nim is also a low-level language (with garbage collection )

    • @aztracker1
      @aztracker1 3 роки тому

      JS vs TS once transported is JS. Runtime differences would be more interesting. V8 vs Spider Monkey etc.
      I'm interested in seeing different web assembly runtimes

    • @theaninova
      @theaninova 3 роки тому

      @@grjj09 Read somewhere Nim was capable of compiling to JS, if it's mainly used with a C backend maybe add it to Go, Crystal & Ruby instead...

    • @theaninova
      @theaninova 3 роки тому +1

      @@aztracker1 True, I included TS for the sake of completeness since it's probably the most popular of them... Different Runtimes would also be interesting, as you said V8 vs Spider Monkey and OpenJDK vs Graal...
      WASM languages stacked against one another and then compared to JS etc would also be super interesting, yes! Forgot about those.

  • @ruiztulio
    @ruiztulio 3 роки тому

    Man I wish I could give 2 likes just for that intro! XD will you make some merch with the drag racing event? I'm all in! (specially because you're donating it)

  • @Qrzychu92
    @Qrzychu92 3 роки тому +12

    next group: Scala vs F# vs Haskell

    • @tokiomutex4148
      @tokiomutex4148 3 роки тому +2

      Haskell wins

    • @daschewie
      @daschewie 3 роки тому

      Seeing that F# borrows from OCaml, it would be great to include that in this list.

    • @alexclark6777
      @alexclark6777 3 роки тому +1

      F# and Haskell will have completed their runs while SBT is still trying to load.

  • @Ruhrpottpatriot
    @Ruhrpottpatriot 3 роки тому +15

    Any reason you didn't show solution_3 with its 7883 passes?

  • @SpinStar1956
    @SpinStar1956 3 роки тому +25

    Name him “Stack” 👍

  • @k_xx
    @k_xx 2 роки тому

    That intro had me in stitches... honestly, much love - all of these videos are so good!

  • @willd4686
    @willd4686 3 роки тому +3

    I see Haskell is on the list. That would be great to see. Or maybe pick some weird ones! SQL sounds nuts!

  • @benjamindepaz8429
    @benjamindepaz8429 3 роки тому +1

    Great video. I’d love to see a comparison of the mobile and UWP language for new windows apps. So Objective-C, Swift, Kotlin, Java and C#.

  • @glenh8179
    @glenh8179 3 роки тому +4

    I'd like to see technical computing languages compared: Fortran, Octave, R, Julia.

    • @orri93
      @orri93 3 роки тому

      maybe not fair to compare fortran that is compiled to R that is interpret

  • @andrewtrumper8392
    @andrewtrumper8392 3 роки тому +1

    RE: using HashMap() for static memory map in Java impl. AFAIK, the static keyword in this context acts basically like a construct does but for a class not an instance. Also, AFAIK, the map isn't going to be optimized to anything. Even accessing it is going to be terribly slow because of autoboxing from int to Integeger. I think you might want to put that stuff in a case/switch statement. The switch WILL become a static memory lookup table as you describe.

  • @mihiguy
    @mihiguy 3 роки тому +5

    If you want to see how fast Java (talking about Oracle's implementation) is with only interpreted code, either run it with `-Xint` switch, or attach a debugger and set a breakpoint in every function at some place that is not reached. JIT will not compile functions that have a breakpoint in them. It's horribly slow compared to the JITed version.
    In fact, there are benchmarks where Java's JIT recompilation will outperform C++ code, but that mostly happens in deep inheritance hierarchies with many virtual functions/methods (due to the fact that on modern CPUs, a "JUMP [register]" instruction is very bad for branch prediction, and JIT will introduce real branches for the most often instantiated objects).

  • @ddanielsandberg
    @ddanielsandberg 3 роки тому

    As others have mentioned, the JVM is interpreted byte code and has JIT compilation and inlining. This also means that code running on the JVM is slower for the first 10000 iterations by several orders of magnitude; possibly sceewing the result. A proper performance test should probably start by executing 10000 iterations before the actual measurement starts. This is a feature that is built into the JMH framework. Maybe I missed something...

  • @gfdgdfgdfgdfggfdgdfgdfgdfg9709
    @gfdgdfgdfgdfggfdgdfgdfgdfg9709 3 роки тому +8

    I would like to see how Actionscript2 and 3 run vs Javascript :O

  • @DylanMatthewTurner
    @DylanMatthewTurner 3 роки тому +2

    I was less surprised because I was recently informed that apparently, Java has actually been using JIT since before C# existed. We're talking like 2000. At least that's what I've been told.

    • @bentels5340
      @bentels5340 3 роки тому +2

      Yeah, HotSpot v1 was released on April 27, 1999 in version 1.2 of the Oracle JVM.
      That, BTW, is one of the things I like so much about the influence of Java: 20+ years of research and optimization of runtime compilers like HotSpot. It's amazing to see how far they've gotten.

    • @anonymoususer6801
      @anonymoususer6801 3 роки тому +1

      In the total benchmark c# is faster than java. Microsoft puts way more effort in the ecosystem than oracle.

  • @bitflaker4872
    @bitflaker4872 3 роки тому +8

    How about calling Baby Stig just "big.LITTLE Bob"?

  • @thomasbagley7142
    @thomasbagley7142 3 роки тому +2

    Love how this has taken off! I think Buzz would be a great name, it's a single syllable like Stig. What about Bill? Or, perhaps a name in memory of an early computer scientist? Babbage, Ada, Allan, I'm sure you know better. Flowers could be a good one, since he thought to use vacuum tubes and that must have been a large step up in performance.

  • @JB-mm5ff
    @JB-mm5ff 3 роки тому +3

    Did you do VB6?
    PS: My vote - name the doll "Chip"

  • @roax206
    @roax206 3 роки тому

    If we are talking about storing Booleans as bits and bit manipulation in Java, I think the most efficient way is the C style bit masking using an int variable though all ints in Java are considered signed so be careful using integer instructions on the value and there is an explicit unsigned shift right operator.
    I have heard rumours that boolean arrays may be stored as bits in modern versions of the JVM/compiler but I haven't checked this.
    Also the Java language seemingly specifies just that garbage collection is automated. The standard JVM supports a number of GC systems (default being clear when low). But I wouldn't be surprised if there is a cmd flag to get the JVM to simulate a smart pointer system (ie clear immediately when no references exist).

  • @BrandtRedd
    @BrandtRedd 3 роки тому +2

    I once had to port some open source C# code to Java. The syntax is similar enough that I simply pasted the C# code into the Java source files, ran the compiler, and fixed the syntax errors. It was surprisingly easy.

  • @joshuavogel861
    @joshuavogel861 3 роки тому +2

    I feel like I'm learning so much about computer performance from watching these videos. at first I was just curious which language is faster but by detailed comparing of languages there is an understanding of what is common between them and from there a much better understanding what is going on behind the scenes. also very entertaining from an obvious master of the field. this is a gift -thank you sir!

  • @Maclabhruinn
    @Maclabhruinn 3 роки тому +5

    The beauty of Java is that you can take your code and run it on a POWER9 CPU for blistering performance. .NET is mainly (though not exclusively) a creature of the Intel world - where hardware performance is good, but not in the same class.

  • @5lickwi11
    @5lickwi11 3 роки тому +2

    Really enjoyed the opening. Glad you are doing these videos.

  • @n-steam
    @n-steam 3 роки тому +22

    Man am I disappointed. I was rooting for C#, its one of my favourites.

    • @igorthelight
      @igorthelight 3 роки тому +7

      Results are strange

    • @Ruhrpottpatriot
      @Ruhrpottpatriot 3 роки тому +18

      Don't be, there's a solution (which he didn't show) that has 7883 passes.

    • @RandalGJunior
      @RandalGJunior 3 роки тому +8

      This solution he showed has a lot of optimization to be done. Like not using Linq, null checks, spawning threads instead using Parallel.

    • @Ruhrpottpatriot
      @Ruhrpottpatriot 3 роки тому +3

      @@RandalGJunior Yeah. It shows some of the really cool C# features that shave of many hours of development time if performance isn't your main goal.
      Here it's mostly a hindrance.

    • @RandalGJunior
      @RandalGJunior 3 роки тому +2

      @@Ruhrpottpatriot C# is a very cool language to write, has a tons of shortcuts and blackboxes.
      It's very easy to get lazy and leave a lot of performance on the table.
      It's very fast to have a good running program, but take some effort to have the best.

  • @theBoomerDoomer
    @theBoomerDoomer 3 роки тому +1

    I remember the Intel bunny suit dancers of the 90s... and the subsequent ad campaign that Apple launched for the G3 PowerMacs poking fun at them. Good memories. :)

  • @Pheidias73
    @Pheidias73 3 роки тому +4

    The c# code was using factor * 3 in the for loop
    for (int num = factor * 3; num

    • @StuartQuinn
      @StuartQuinn 3 роки тому

      Raise a PR?

    • @weisj
      @weisj 3 роки тому +3

      Haven’t you read the annotations in the video? The benchmark ran with a corrected version that used factor*factor instead of factor*3

    • @johanrg70
      @johanrg70 3 роки тому +3

      He has annotations about that at 12:02, so this was not in his actual test.

    • @Pheidias73
      @Pheidias73 3 роки тому

      @@weisj I do not recall those being there when i watched the video earlier

  • @KitsuneAlex
    @KitsuneAlex 3 роки тому

    I mean, if you think about it it makes sense: both Java and C# are compiled into some intermediate bytecode and are then JITed by the VM/runtime into native assembly code. And it turns out that both the Java VM and the .NET runtime are pretty well optimized at this point since they've been around for a while. You could go a step further and write some code examples by hand, hand-optimized bytecode/IL and then run that.

  • @xSugknight
    @xSugknight 3 роки тому +6

    To be honest i skipped to the results, so i might have missed it: What kind of JVM was used in this experiment? I found the graalVm to be faster by a factor of 2 in many occassions (but not in every)

    • @bluesillybeard
      @bluesillybeard 3 роки тому

      Probably later than 11, 16 I bet. Not sure though, might say it in the github.

    • @orbyfied
      @orbyfied 3 роки тому

      he said as a reply that he used JDK 7... bruh

    • @xSugknight
      @xSugknight 3 роки тому

      @@orbyfied yeah i found it - but thanks anyway

    • @bluesillybeard
      @bluesillybeard 3 роки тому

      @@orbyfied That's impressive, considering it's score.

    • @orbyfied
      @orbyfied 3 роки тому

      @@bluesillybeard yeah, but i bet that if he used JDK 16 and disabled the GC or used the new GC flags it would be like so much faster.

  • @Nusremmus
    @Nusremmus Рік тому

    Love this channel. Very informative and that deadpan humor kills me. I would say this guy should be on Carson, or Letterman, but ... well you know.

  • @dhombios
    @dhombios 3 роки тому +3

    It would be interesting to see the difference between how good the same Java program used in this test performs using JVM and Graal (oracle java aot compiler)

  • @DavidWonn
    @DavidWonn 3 роки тому +1

    I remember loathing those Intel guys in the commercials, mostly because of the time I spent in getting a Pentium III-based PC built, only to see them advertising the IV shortly afterward.

  • @evil_me
    @evil_me 3 роки тому +20

    "he's not the stig, but he is the stigs silicon based cousin"

    • @c4ashley
      @c4ashley 3 роки тому +1

      😂👏🏻

  • @JATmatic
    @JATmatic 3 роки тому +1

    I was putting off subscribing, but after that many explosions, I have no excuses left.

  • @kungfujesus06
    @kungfujesus06 3 роки тому +13

    So the implications of Java bytecode you're making aren't entirely accurate. OpenJDK's hotspot JIT has had a lot of optimization over the years and can still do things that .NET can't. For instance, during loop unrolls, it can actually autovectorize to the target architecture. It's somewhat limited from what I've read (only works for explicitly counted loops), but I've seen the emitted machine code in some instances and it's pretty decent.
    Also as far as being harder to target functional languages - I don't believe that's true, either. Scala and a number of other languages sit atop of the JVM.

    • @FilipCordas
      @FilipCordas 3 роки тому

      Clojure runs fine on Jvm and it's been working for years, but it's definitely harder to work with then .net

    • @killmeplease5389
      @killmeplease5389 3 роки тому +2

      In uni had had one lecture where my professor was talking about java and c# performance. Most of the time it just comes to the fact that java was slower so they worked on a better compailer and .net suffered stagnation because it had the mentality of c++ where the programmer has the freedom to optimize how he wants. And if you know your shit you can really bust c# to good c++ code.
      But slower or faster than java I don't care. I still prefer c# over java just for the fact that it is just so better making web apps when you started with node.js and it just the same 😉

  • @phacus
    @phacus 3 роки тому

    Next: VIm _v._ Emacs
    BTW, I'm gonna subscribe. Algorithm brought me here 2 times and this is a solid channel.
    Thanks, Dave.

  • @tobiasericsson402
    @tobiasericsson402 3 роки тому +3

    Forth is not on the list. Yet, at least. Really interesting language.
    Smalltalk also could be included.

    • @mattym8
      @mattym8 3 роки тому +1

      Edit: there are implementations for Forth and Smalltalk already.

    • @tobiasericsson402
      @tobiasericsson402 3 роки тому

      @@mattym8 Thanks! I didn't have an updated list.

  • @sledgebox
    @sledgebox 3 роки тому +1

    I'd like to see the differences in performance when JIT compiling is not a factor. For C#, compile using the ReadyToRun option. Java has something similar.

    • @DavesGarage
      @DavesGarage  3 роки тому +1

      I'm pretty confident that by the time we bench, both are fully JIT compiled. I'll check into ReadyToRun!

  • @henrikostman4474
    @henrikostman4474 3 роки тому +4

    I’m actually shocked that Java won this race! Since the test seems to have no warmup part, the first xxxx iterations would have been run interperated, before the JIT kicks in, find the hotpaths and compile those to native code. I though that disadvantage would have given C# a good headstart and ultimately winning the race. For all Java benchmarks you should really run the code a couple of thousand interations before you start the clock, just to let Java find out what to optimize. Java has never been a quick starter, its optimized for running programs for days, not seconds.

    • @Syscrush
      @Syscrush 2 роки тому +1

      Same here.
      I'm curious now about how this would look with some warmup added to the Java solution.
      I'm also curious about how the comparison would look for a problem that requires a really large amount of memory (like >100GB), as C# really outshines Java in those conditions in my experience (though that experience is old and may not still hold up).
      In any case, great series. It's really interesting seeing how longstanding assumptions can get shaken by real world data.

    • @RetroDawn
      @RetroDawn 2 роки тому

      Actually, there is no need to do a warmup with Java. If you want a prg to be JIT'ed right out of the gate, you can merely pass an argument to the java cmd.

    • @henrikostman4474
      @henrikostman4474 2 роки тому

      @@RetroDawn Maybe so, but was the tests run with that flag??

    • @Syscrush
      @Syscrush 2 роки тому

      @@RetroDawn I think you're forgetting about hotspot optimization, which really benefits from a warmup.

  • @secretagent3712
    @secretagent3712 3 роки тому +2

    Please rerun C# test with DateTime instead of Stopwatch. The reason is that Stopwatch doesn't actually measure time. Instead, it counts ticks. Accuracy of ticks will depend on hardware, and it can possibly be affected by the program itself. Now, when I made a simple stopwatch program with Stopwatch, it lagged 1-2 seconds for every minute that has passed. That would give the appearance that less time has passed, and therefore, a higher score.
    I could be wrong, and the shown score could be accurate, but it should be verified.

  • @skyletoft
    @skyletoft 3 роки тому +4

    That intro was great

  • @jonathanreiter2852
    @jonathanreiter2852 3 роки тому +1

    From a former Intel employee: Pao could be a good name for Baby Stig. Short for the infamous Intel chip lifecycle that supplanted the tick-tock model (process-architecture-optimization).

  • @RonnyJakobsson
    @RonnyJakobsson 3 роки тому +4

    Love the intro. Made me smile 😁

  • @attilazimler1614
    @attilazimler1614 2 роки тому +1

    Instead of Aggregate for separating the string entries with commas, string.Join() could have been used too. Just a guess, but I think it would be faster (fewer function calls).

  • @keithv708
    @keithv708 3 роки тому +3

    I loved the intro Dave 😁

  • @JawidHassim
    @JawidHassim Рік тому +1

    Hi Dave, I don't know any other way to get hold of you. You HAVE TO do a rematch but this time: .Net 7 AOT Compilation for C#
    Please and thank you :D

  • @CallousCoder
    @CallousCoder 3 роки тому +4

    My bet from previous experience is Java. Unless it’s the new .Net Core that’s been optimized really well and runs faster than Java 11. So the runtime is the determining factor.

    • @bjbegui
      @bjbegui 3 роки тому +1

      I wonder if he will cover Java + Graalvm

    • @TheRudi9719
      @TheRudi9719 3 роки тому +1

      I wonder if Java 11, 14, or 16 would effect performance too

    • @CallousCoder
      @CallousCoder 3 роки тому

      @@TheRudi9719 to an extend, for sure. Runtime environments and JIT compilers are revised every version.
      The biggest change I saw was when we ported our IdM solution from Java 6 to Java 8 and we knocked off another 15 minute from our 1.5 hour. Which was very much database, directory and memory bound. The GC was so much more optimized in Java 8 that when we cleared all the identity objects from an organization, the heap was cleaned a lot faster. GC could pretty much slow down the system for 30-80 seconds.
      For sheer single threaded maths like Dave’s test, I doubt that runtimes have a significant influence.

    • @CallousCoder
      @CallousCoder 3 роки тому

      @@bjbegui have you used GraalVM and if so what are your experiences? I have not yet used it. But otherwise you can run it yourself, Dave has the source code released.

    • @davidwhite2011
      @davidwhite2011 3 роки тому +1

      What is Javas parallel extensions like. Pretty easy to write something like this and parallel it in .net. I have never done anything in Java.

  • @OsaPL1
    @OsaPL1 3 роки тому

    I think nowadays, being a programmer is more than just "I know how to write in this language" or "I know this toolset", its a lot more about your ability to tinker around with solutions, and adapt with the already existing codebase, frameworks, tools, other team members and so on.
    I am a total sucker for c#, and I've done basically eveything, from dotnet framework to core, from wix bootstrap installers to blazor dynamic webpages, from winforms to avalonia... yet I still did lots of things using other languages.
    I think programming is more of a key ring, and everything else are just keys that you add, not all fit, but its worth to add more, cause as everything, the more you do smth, the easier it gets, the better you get.

  • @mysticknight487
    @mysticknight487 3 роки тому +2

    Could you run the Java using GraalVM or TornadoVM? Both offer compile to native which may increase the number of runs as it speeds up startup time.

    • @RustedCroaker
      @RustedCroaker Рік тому

      Most of the time AOT compilers produce less optimized code then JIT ones. Because "warmed up" JIT code has an advantage of being constantly profiled on the runtime.

    • @mysticknight487
      @mysticknight487 Рік тому

      Sure but in this case the startup time may be a large enough portion of the execution time that the JIT optimization doesn't make up the difference in startup time. I guess I should try to compile to native using one of the compilers and run the numbers vs openjdk on my machine to check. I may post an update later today with numbers, otherwise I got tied up in other life to try

  • @RealCheesyBread
    @RealCheesyBread 2 роки тому +2

    I'm amazed that Java actually managed to outpace C#. I totally expected C# to beat Java by a huge margin. Especially considering just how incredibly limited the JVM instruction set is.

    • @RetroDawn
      @RetroDawn 2 роки тому

      Are you very familiar with Java Bytecode? It's not particularly limited. And, contrary to MS's marketing naming of .NET's CLR/CIL (which Dave has bought, hook, line, and sinker), they were not at all designed to be more language-agnostic than Java. They are actually more tied to C# than the JVM/Java Bytecode are to Java.

    • @RealCheesyBread
      @RealCheesyBread 2 роки тому

      @@RetroDawn Im quite familiar with Java bytecode, and I have written a number of utilities that create classes at runtime/load time by generating bytecode.
      Im not very familiar with the C# IL code though except that it follows some similar semantics to Java such as being stack based. Also that it seems to be more extensive.

  • @brunocesar7811
    @brunocesar7811 3 роки тому +3

    Hello guys, where’s the leaderboard?
    Impactful intro btw :D

  • @mworld
    @mworld Рік тому

    When bench marking c++ / c#/ java code that does a lot of memory allocations (like breadth first search) I saw a vast difference, with c++ coming out on top since pointers rule. This kind of test does not lean on the cpu so much, but rather the languages ability to use as little memory and as few allocations as possible.

  • @stevenhe3462
    @stevenhe3462 3 роки тому +4

    I always use System.nanoTime instead of System.millisecond

  • @hikaru-live
    @hikaru-live 3 роки тому +2

    You may want to single out some results (for example, C++ scores) as an integer-only benchmark for the processors.