Announcement

Collapse
No announcement yet.

Miguel de Icaza Talks Up WebAssembly Greatness

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Danny3
    replied
    Originally posted by Zan Lynx View Post

    It has been a long time since you could read the Javascript code and have it make any sense. First it's compile to JS from Typescript, then it is compressed and obfuscated so every function is called "f" or "g". CSS is often done in a similar way with all of the classes and object IDs named junk like "c1" and done half in CSS text and half in Javascript.

    WASM is no worse. It can be decompiled and read about the same as obfuscated Javascript. At least it can't do x86 assembly tricks like computing a jump into unaligned code at a +1 byte offset or using Windows SEH to execute the real code during division by zero.
    Maybe yes with the user friendly names, but still you can see the function that are trying to be used like navigator.geolocation.getCurrentPosition(showPosition);
    I don't really thing that you can obfuscate everything in Javascript.
    But anyway, I will see what the future brings, if there are more advantages or disadvantages.

    Leave a comment:


  • cynical
    replied
    Originally posted by Luke_Wolf View Post
    Real world C# programs are vastly more memory efficient than Java programs, they are within the same order as similar C++ programs. Toy C++ programs that don't require automatic memory management schemes like parent child hierarchies can still be more efficient but that's the difference we're talking about here. I made a post about this years ago where I compared the memory usage of comparable real world C++ and C# programs, and some Java programs thrown in for comparison if you want to look back through my history. If you want a simple comparison check out the memory usage of Monodevelop vs KDevelop or QtCreator vs your Java based IDE of choice with a decent sized project loaded.
    Based on what? Value types are nice but concluding that C# is "vastly more memory efficient" based on that alone is ridiculous. Do you realize that if you add your value type to an ArrayList, it is now an object? Do you realize that stack allocation is not guaranteed in the first place? Comparing two IDEs and trying to conclude something about the languages based on that is completely ridiculous. If C# was as efficient as C++, you wouldn't have so many posts on the internet complaining about its memory usage.

    You have a bias towards C#, which is fine if you like that language, but there have to be significant differences between the way Java and C# handle memory for there to be significant differences in memory usage, and that simply isn't the case. They both have fairly large runtimes and rely heavily on reference types.

    Leave a comment:


  • cynical
    replied
    Originally posted by Luke_Wolf View Post
    However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
    That's not how modern GCs work. The size of the heap region for eden/young generation (short lived objects) is quite small. When it becomes full, a quick collection is done and live objects are either promoted to the next region or deallocated. You do not get "obscene amounts of garbage" waiting to be collected, not unless you are purposefully creating and holding on to object references.

    Originally posted by Michael_S View Post

    To jump a bit further on this point, long-lived objects go on your heap and short-lived objects like variables inside a function that don't escape the function body (are not returned to the caller or placed in a list or something) should go on the stack. The stack 'freeing' of objects as you exit the functions is the most efficient memory management you can do, the running code is going to move the stack pointer anyway.

    Did I say all of that about right?
    Reference types never go on the stack. They always go on the heap and are managed by the runtime. Value types are stack allocated. In Java you have actual primitives (int, float, etc), and in C# you do not. There you get structure/value types which can resemble lightweight objects (and have certain restrictions), and what happens is they are boxed/unboxed so they can be treated like objects. So if you tried to add something like the integer 5 to a list of objects, it would first be converted to an object before being added. (so if you add your value type to a collection like an ArrayList, it is getting boxed behind the scenes and using EXACTLY the same memory that a Java object would use, so it's not as clear cut a distinction as you might think)

    The tricky thing is that Java does scalar replacement, so if you have a simple object that you create and use only in your method body, it may not even be an object by the time the JVM uses it because it could be transformed into simple stack allocated primitives.

    Both Java and C# are very good about dispatching short-lived objects because they use generational GCs. Deallocation costs almost nothing. Allocation is also very cheap. So this point about Java wasting a lot of memory is total nonsense because it is very good about releasing heap allocated objects. What matters is not the total number of objects you create, it's whether you are creating lots of long-lived objects or how quickly you are creating short lived ones. The rate of allocation, if high, could put pressure on the GC and reduce performance, but there will be no "wasting memory" since they are destroyed quickly enough and replaced by new ones.

    One of the challenges for Java performance has always been the boxing of primitive types (which introduces a big penalty on math heavy operations). When value types are introduced, they will alleviate that greatly.
    Last edited by cynical; 06 March 2020, 03:29 PM.

    Leave a comment:


  • bug77
    replied
    Originally posted by Luke_Wolf View Post

    It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

    However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
    JVM designers have noticed this years ago. It's why the GC has a young and a tenured generation zone. Young generation (stuff that could go on the stack, but didn't) is collected separately then tenured (long lived objects, less likely to be collected). Is JVM's memory's the most efficient? Not really, but that was never a goal. Is the GC doing the best job it can? Probably not, out of the box; but it will if you tune it right.

    Of all the differences between .Net and Java, I confess stack vs heap allocation was never something that struck me.

    Leave a comment:


  • Michael_S
    replied
    Originally posted by Luke_Wolf View Post

    It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

    However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
    To jump a bit further on this point, long-lived objects go on your heap and short-lived objects like variables inside a function that don't escape the function body (are not returned to the caller or placed in a list or something) should go on the stack. The stack 'freeing' of objects as you exit the functions is the most efficient memory management you can do, the running code is going to move the stack pointer anyway.

    Did I say all of that about right?

    The JVM is riding the cutting edge of efficient garbage collection technology. The ZGC and Shenandoah garbage collectors, for example, are an amazing piece of work. But Java has to ride that cutting edge to be performance competitive. And that's only performance (speed of execution, total throughput) competitive, Java isn't memory competitive with C#, let alone C++ or C.

    Leave a comment:


  • Luke_Wolf
    replied
    Originally posted by bug77 View Post
    Luke_Wolf I'm confused, are you saying throwing 1MB of data onto the stack uses less RAM than throwing the same amount on the heap?
    It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

    However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.

    Leave a comment:


  • Luke_Wolf
    replied
    Originally posted by cynical View Post

    No, Java is not throwing everything on the heap. That's what would happen if you had no optimizations at all (scalar replacement, escape analysis), but thankfully the JVM does do them in many cases. Also, you have to box value types in C# as well when doing anything interesting with them, and I'm not aware of C# applications being particularly memory efficient compared to Java, so this is all kind of academic stuff.

    (besides, the main benefit here would not be a reduction in overall memory usage, it would be increased performance from reduced object allocations and GC pressure, which is something that counts as an advantage C# has over Java for now)
    Real world C# programs are vastly more memory efficient than Java programs, they are within the same order as similar C++ programs. Toy C++ programs that don't require automatic memory management schemes like parent child hierarchies can still be more efficient but that's the difference we're talking about here. I made a post about this years ago where I compared the memory usage of comparable real world C++ and C# programs, and some Java programs thrown in for comparison if you want to look back through my history. If you want a simple comparison check out the memory usage of Monodevelop vs KDevelop or QtCreator vs your Java based IDE of choice with a decent sized project loaded.

    Originally posted by cynical View Post
    Changing the bytecode specification is a big deal... it's also completely unnecessary. They are implementing value types and generic specialization in what they call Project Valhalla.
    Good luck with that. Project Valhalla is trying to work around the problem rather than actually solve it.

    Leave a comment:


  • cynical
    replied
    Originally posted by Luke_Wolf View Post
    It's cute of you to say that, but there's a reason that JVM programs are uniquely memory heavy, and that reason has nothing in particular to do with the underlying architecture of say a Java vs a C# application. In fact most of the broad strokes of how they're written are going to be the exact same, it is more in the fine strokes where they differ, and therefore an average C# and Java program should be using a similar amount of memory. Well they for all intents and purposes are (with the caveat mentioned in my previous post), the difference is that in the real world Java is throwing everything on the heap and you're at the mercy of the Garbage Collector whereas .NET handles about as much as a program written in other languages on the stack, and so the automatic memory management of the stack limits the impact on the memory overhead of the program.
    No, Java is not throwing everything on the heap. That's what would happen if you had no optimizations at all (scalar replacement, escape analysis), but thankfully the JVM does do them in many cases. Also, you have to box value types in C# as well when doing anything interesting with them, and I'm not aware of C# applications being particularly memory efficient compared to Java, so this is all kind of academic stuff.

    (besides, the main benefit here would not be a reduction in overall memory usage, it would be increased performance from reduced object allocations and GC pressure, which is something that counts as an advantage C# has over Java for now)

    Originally posted by Luke_Wolf
    They were almost as bad as Adobe. Sun Microsystems could have very easily have resolved the issue without forcing everyone to rewrite their software, a simple recompile with the artificial delineation between primitive types and Object derivatives being removed from the JVM ByteCode would have been enough, to be quite clear there's nothing in Java's fundamental language design that says primitive types can't be Objects and participate in generics.
    Changing the bytecode specification is a big deal... it's also completely unnecessary. They are implementing value types and generic specialization in what they call Project Valhalla.
    Last edited by cynical; 05 March 2020, 02:00 PM.

    Leave a comment:


  • bug77
    replied
    Luke_Wolf I'm confused, are you saying throwing 1MB of data onto the stack uses less RAM than throwing the same amount on the heap?

    Leave a comment:


  • kpedersen
    replied
    Originally posted by Luke_Wolf View Post

    there's a reason that JVM programs are uniquely memory heavy, and that reason has nothing in particular to do with the underlying architecture of say a Java vs a C# application..
    Java and .NET *are* the same technologies based on the ancient Alef, Limbo design from the Plan 9 days. They have the same problems and "solutions".

    Check out escape analysis for Java using stack memory
    https://en.wikipedia.org/wiki/Escape...#Example_(Java)

    You can "box" data in VB.NET (and its sibling, Csharp.NET) but ultimately it is up to the VM processing the Bytecode to try to do the right thing. Just like the JVM.

    Leave a comment:

Working...
X