HNHacker News
TopNewBestAskShowJobs

readittwice

531 karma · joined September 3, 2016

submissionscomments
readittwice··on A letter to Steven Pinker about global poverty
To be fair Pinker wrote that in a private mail. When you criticize this, then also let's not forget what on the other hand Hinkel wrote in his article published in the Guardian newspaper:

> It is madness – and no amount of mansplaining from billionaires will be adequate to justify it.

We can certainly discuss about the data and how to interpret it, but using such phrases in a newspaper-article isn't really helpful either.

readittwice··on Convincing engineers to join your team
I think that's a great way of interviewing! But don't you fear this only works for smaller companies? Imagine some company like Google or Facebook would do that: I would expect people to just start learning answers by heart..
readittwice··on Java’s new garbage collector promises low pause times on multi-terabyte heaps
How many languages use this approach though? This probably also removes one major advantage of RC'ed systems though: deterministic destruction (e.g. close resource as soon as last reference disappears). And suddenly you need some kind of runtime too.
readittwice··on Java’s new garbage collector promises low pause times on multi-terabyte heaps
>> - no sharing across threads, otherwise locking is required for refcount updates >That is not true. Most atomic refcount implementations are lockfree (you do need synchronization though). This optimization has nothing to do with tracing. Given that you also need synchronization for tracing garbage collection (including frequent stop the world pauses in most cases, albeit brief ones), I don't think this is even really an advantage of tracing at all.

Not sure I agree with that. Copying references between local variables and reads/writes from heap all require expensive atomic operations for RC when they can't be optimized away. That's a major performance problem for languages like Swift. I do not say that one is better than the other, but this is exactly where tracing GC's shine compared to RC.

In the case of ZGC these doesn't require atomic operations, you need a read barrier for reading references from the heap though. But do not conflate tracing GC's read & write barriers with atomic barriers.

readittwice··on GoAWK: an AWK interpreter written in Go
gawker might have been even better ;)
readittwice··on Engineering whiteboard interviews: yay or nay?
You certainly have a point. But those whiteboard interviews people complain about are usually a bit harder than just solving FizzBuzz.
readittwice··on France Bans Street Harassment, Approving Hefty Fines for Catcallers
I know women that have to endure that almost every day, but the police can't do anything about that. The police can't be everywhere and even if they would there is not much they can do if people approach women by saying something like "hey beautiful woman".
readittwice··on Why the New V8 Is So Damn Fast
I don't think so: TypeScript/JavaScript-Types are too coarse-grained for optimizations: For example number is a double in JS. For generating good machine code you really need to know whether the number is int or double. The same for string: Depending on the JS engine there are actually a lot of different string types.

Even if we consider that good enough or somehow solved, understanding type annotations only helps you reaching peak performance faster. It doesn't really make peak performance faster.

Also there are the PyPy and Dart devs that in theory could use type annotations, but both don't. For PyPy they even have an entry in the FAQ: http://doc.pypy.org/en/latest/faq.html#would-type-annotation...

readittwice··on GCC 8.2 Released
What I mean: As a compiler writer you can't just create GIMPLE-IR and then pass it to GCC. You always need to go through GENERIC, which is actually intended to be the AST of your language. Of course you could argue that you treat GENERIC not as an AST but something similar to LLVM-IR and keep your language AST outside of GCC. But does anyone do that? The reason for that is that the IR doesn't contain ALL the information, there is also some global state stored in global variables, etc. Also since the IR is only internal it is not as well-defined as LLVM's IR.

This missing separation is even a problem for writing tests in GCC: Often it would be quite easy to write a small program in GIMPLE-IR (or RTL) and test your optimization pass against it. But you can't write GIMPLE-IR (it needs to go through GENERIC all the time), so you need to write a C file that is then translated into the IR you want to test again. This is sometimes not so easy with all that different optimization passes that run before your pass and hopefully that doesn't change in the future either.... There was some work on this (I don't know about the current status) but almost all of GCC's tests are still integration tests against C files (I think they addressed this by extending the C-front end to be able to parse functions marked with __gimple as Gimple-IR). Also GIMPLE didn't start as a separate IR. It started as a more restricted tree-structure. Even today operands are still tree's and optimization passes are called tree-<something>.c.

With LLVM I can write a toy compiler that outputs LLVM IR with printf and then just pipe it into llc to compile it. That's pretty cool. I didn't want to imply that GCC has NO separation between IRs but the whole story is much messier compared to LLVM. Which is actually fine, LLVM is much younger than GCC and could learn a lot from it. And GCC is still pretty great in the use cases it was intended for.

readittwice··on GCC 8.2 Released
I guess both. GCC is very good for compiling C/C++ to machine code. But if you want to write a new language and reuse an existing compiler pipeline (Rust, Swift,..) or write a new tool based on a C++-parser (clang-format, clang-tiny, clangd,...) then LLVM is the way to go.

LLVM-IR has enabled this nice separation between the language front-end and the compilation back-end. GCC could have done that too: they didn't for political reasons. Why? Someone could have used GCC's C++ front-end for its proprietary compilation pipeline. Today this is nearly impossible to change in GCC.

There are also some other advantages for LLVM I like: it supports multiple architectures in a single binary. With GCC I need to compile the compiler either for x64 or arm but not both. GCC is still great but it's not surprising that LLVM is so successful.

readittwice··on Is WebAssembly the Return of Java Applets and Flash?
My answer was in reply to "WASM enables nothing". I argue that WASM is faster than JS, therefore it enables new applications.

I didn't make any claims about Java Applets or Flash performance.

readittwice··on Is WebAssembly the Return of Java Applets and Flash?
Not sure if I agree. I would still say that WASM enables new types of applications. Of course you could have compiled all that new WASM applications to asm.js or even JS as well. But it would've been slower: maybe even unusable slow. That's why I think WASM enables new types of applications. It's the same as in the past where faster JS engines enabled richer web applications like GMail, etc. Now we get games in the browser and large native applications like AutoCAD.
readittwice··on The internals of testing in Rust in 2018
but incremental builds only take a few seconds when bootstrap is disabled...
readittwice··on The future of WebAssembly – A look at upcoming features and proposals
No, repolfx didn't. There were some security bugs with WASM, but why shouldn't have that happened with Java Bytecode? Also the JVM isn't immune to security bugs either.
readittwice··on The future of WebAssembly – A look at upcoming features and proposals
Let me be clear on this: I am NOT saying that Java-Bytecode sucks. I am simply saying that WASM is better for the Web's use case. There is no shame in that, WASM was designed for that and could learn from the experience with many bytecode formats and also asm.js.

Even if we would agree that the JVM is as good as WASM as a language-agnostic bytecode, WASM still makes sense since it doesn't come with all the baggage of the JVM like class files, many bytecodes that exactly match the Java semantics but can't be used in other languages. Browser-vendors would still have to add new bytecodes for common operations for both size and speed reasons. So it made sense to design a new bytecode format. WASM even allows streaming compilation: The browser can start compiling bytecode before it downloaded the whole file.

Yes, there are a few features missing from WASM. But just look how many applications have already been compiled for the web. The missing features are not that relevant for many large existing and performance-sensitive native applications written in C/C++. We don't need to rewrite this applications in JS. I mean JS wouldn't even be fast enough for that anyways. That's what WASM was designed for and even according to you WASM is better suited for this than Java-Bytecode.

Inline assembly and vector extensions would also be problematic in Java Bytecode.

readittwice··on The future of WebAssembly – A look at upcoming features and proposals
JVM-bytecode isn't ideal as a compilation target for C++, Rust, etc. And that's okay - it was designed for a different purpose.

There are very good technical reasons for WASMs existence. JVM-Bytecode for example is very Java-focused, WASM doesn't need class-files or many bytecodes like invokevirtual. For supporting C++/Rust it doesn't even need GC.

Bringing large applications like PSDFKit, AutoCAD or games into the browser is certainly getting the web forward. Sure, WASM isn't intended for manipulating the DOM. This is still JS's job (at least for the foreseeable future).

readittwice··on The future of WebAssembly – A look at upcoming features and proposals
All of your "serious flaws" are actually fixable. Obviously WASM tooling isn't as mature as other older ecosystems, this will get fixed over time.

I don't think JVMs where without any security bugs, since WASM is mainly used in browsers right now, security is a MAJOR concern. Java-Bytecode was designed for a different purpose. Try to compile a language with multi-inheritance to Java-Bytecode, it's a pain. WASM is designed in a more language-agnostic way, that's why GC and Exception Handling is much harder to specify than in the JVM.

BTW: GC'ed languages can already be compiled to WASM: they more or less "just" need to compile the GC to WASM too. The GC proposal would only allow to reuse the embedder's (most likely the browser) GC.

readittwice··on The future of WebAssembly – A look at upcoming features and proposals
> Actually, the CLR supports pointers and the JVM can run arbitrary LLVM bitcode (so C, C++, Rust etc) in a memory safe way with bounds checking and garbage collection these days. Check out Sulong and Safe Sulong:

AFAIK there is no Java-Bytecode involved for this and to optimize the AST-interpreter to something faster you need the Graal-Compiler, most JVMs can't do this. There is no C++/LLVM/Rust to Java-Bytecode compiler that is widely used, while this exists for WASM. Even a huge Codebase like AutoCAD was compiled for the Web. Java-Bytecode wasn't designed for this, you could theoretically do the same with Java-Bytecode but it would probably be much slower. Simply because Java-Bytecode wasn't designed for this purpose.

Java-Bytecode is notoriously hard to verify, WASM is more strict and therefore verification is easier. (With verification I mean the process in the Browser/JVM that checks if the bytecode is actually valid). WASM only allows structured control flow, no arbitrary gotos like Java. This makes the compilers job much easier, many JVMs actually just bail out on irreducible loops and therefore such code might not get optimized. OTOH WASM-Bytecode wasn't designed for interpretation.

I don't know why there is this heated discussion. WASM had the chance to learn from the mistakes in Java's Bytecode and both bytecodes were designed for different purposes after all. Java Bytecode was designed for Java, WASM for being a language-agnostic compilation target. Supporting GC in Java-Bytecode for example is much easier than having a similar thing in WASM.

readittwice··on Getting to Go: Garbage collection and runtime issues
I think you are right, but I can still see why they chose certain trade offs. The most common use case for Go seems to be as servers (right? I am not a Go developer...) where latency is important, non-moving GC allows them to have low latency while not having the throughput hit of read barriers. Obviously this comes with certain trade-offs: e.g. slower allocation performance. OTOH interfacing to C becomes a bit easier, although that's even without that quite complicated in the case of Go. Also the language uses interior pointers a lot, which is simply more complicated with a moving GC.

> So they had a GC that scaled better. But it got killed by, you guessed it, the needs of batch jobs

Even in the JVM where you have multiple specialized GCs, the developers also look at each GC in workloads it wasn't designed for and that also seems to influence design decisions. For me this just means they focus on the server use case (=latency) but not at the cost of 50% throughput hit for the compiler (=batch job).

readittwice··on Getting to Go: Garbage collection and runtime issues
Isn't JSC kind of an exception to this? JSC has a generational non-copying GC. It uses bump-pointer allocation for empty blocks (block=memory with objects of same size) and then switches to allocation via free-list if the block is full.

For implementing the generational GC they simply use sticky mark-bits.

readittwice··on V8 release v6.8
Sure, the tmp-var-approach could be slower in some weird edge cases but probably only slightly, while the array-swapping approach could be much slower if the JS-Engine doesn't implement this optimization at all or this code-pattern is run in interpreter or baseline compiler.

Not arguing you should do such micro-optimizations, but generally writing "simpler" code should also allow less sophisticated compilers to generate fast code.

readittwice··on GCC 8 Link Time and Interprocedural Optimization
AFAIR GCC bootstrap builds by default with "-g -O2". There are 3 stages: 1) use system compiler to compile GCC's source code, 2) use resulting binary to build same source, 3) use binary from 2) to build source one more time. After all stages the binaries from stage 2 and 3 are compared byte for byte if they are identical.

Bootstrap failures are taken very seriously by the GCC developers. So I really doubt that -g and -O* lead to non-deterministic builds.

readittwice··on 90-minute ‘super commutes’ more common as Bay Area housing shortage intensifies
European here. After moving I was commuting for about 105 minutes with public transport, about 70 minutes by car. Was using public transport most of the time though, but I couldn't do this more than a few months. There is so much time and money that goes into commuting, it is insane... Going to the doctor/bank/shopping/etc. was always problematic because then I would have to stay in the company late into the night. When you come home you are just tired and want to rest. Pay wasn't even in the near of being good enough to justify that.

Right now I am working from home which (after some months of experience) I enjoy much more. Also got a substantial pay raise when changing jobs and at the same time save money on the commute.

Still glad I was at my old job since it got me into another field of software engineering and I learned a lot. Don't think I would've got my current job without it.

readittwice··on Apple Plans to Use Its Own Chips in Macs from 2020, Replacing Intel
AFAIK the ARM license doesn't allow to invent arbitrary extensions to the ISA. So this might not be allowed.
readittwice··on Dropbox S-1
For me the reason is that Google Drive doesn't work on Linux.
readittwice··on How a fix in Go 1.9 sped up our Gitaly service by 30x
AFAIR JRuby creates a Java class for each Ruby method. Classes were part of the Permanent Generation, so sometimes this generation was too small escpecially when using Rails. It was enough to just increase the size of this generation with -XX:MaxPermSize (-Xmx doesn't increase the permanent generation's size).

The Permanent Generation was named that way since objects in there were never collected. For most applications this isn't really a problem. Running JRuby+Rails just allocated a lot of classes in this generation, so the default size was too small. But still, the permanent generation was quite small compared to the heap size.

I wouldn't really call the GC bad because of this, IMHO they were already quite good back then. And in Java 8 the permanent generation was replaced with the Metaspace, objects in there can be free'd and the Metaspace can be expanded at runtime so it's less likely to get these OOM errors for the permanent generation.

readittwice··on The new microcode from Intel and AMD adds three new features
Thanks for the nice writeup!
readittwice··on Rust in 2018: easier to use
Yep, that's exactly what I would also like to see.

AFAIK there is some work on a GC in Rust, but it doesn't take away the borrow checker like you wished ;) So you will still need to use `.borrow()` and `.borrow_mut()`.

A language similar to Rust but with GC (and no borrow checker) could be quite useful for a lot of applications out there. Basically Go but a more "modern" language.

readittwice··on Finding a CPU Design Bug in the Xbox 360
Is there a way to "recognize" this? For example why the blue blobs and not the green ones?
readittwice··on Using Java 9 Modularization to Ship Zero-Dependency Apps
> Another promoted benefit of bytecode is compile-once-run-anywhere. However, I think this is a hoax.

I was once working on a large project on the JVM: our Fat-JAR was really working on Linux, Mac and Windows. The exact same JAR. And it didn't matter on which system we have built that JAR. This may not be possible for every use case - but I don't think it is a hoax.

> It is not special, for script languages code runs anywhere without compiling.

IMHO scripting languages like Ruby, Python, etc. are quite hard to deploy, especially if they have dependencies. In comparison to languages like Java, Go or Rust.

← PreviousPage 3 of 6Next →