Rust doesn't enforce style anywhere. You can turn off all style warnings at once too with `#![allow(bad_style)]` or a command line flag. By default it just warns. That's not enforcing.
Come on, even that flag's name is ridiculous. They basically say, for example, that writing camel case, which is the preferred style in most of the projects I've seen, is bad style. Do they like being unnecessarily antipathetic? People think about their personal preferred style for years, and they have very good reasons for choosing them. And in _many_ cases, it's exactly the style that's called bad by Rust's creator…
In some cases skirting style can be harmful (e.g. in match statements there's an ambiguity with enum variants and variable bindings that is not an issue because of the style lints).
But I get your point. I think people would be open to that naming change if you file an issue.
Since you asked, there's an assembly comparison on pages 5-6 of http://www.jilp.org/vol5/v5paper12.pdf and a performance comparison on page 12 of http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90.... . Note that the "inline threading" in the second paper is a further optimization that hasn't been brought up here yet. In summary, the assembly of the goto version is much shorter and there's a 10% speedup over…
That's about what I expected, contrary to the 2-4x times speedup mentioned above. Still, I can imagine in isolated cases you really would get a better number than that 10%. So, for code where performance is super important and where the effort of the optimization and lack of transparency is outweighed by the performance boost this makes sense.
Yes, that 10% is an average over seven benchmarks. The numerical one gets a 25% speedup, the one with a bunch of exceptions doesn't benefit at all. The funny thing is, if you're interested in performance, you're probably going to be writing a JIT, so this optimization is really just a stop-gap measure. In fact, the inline threading I mentioned is a kind of cheap JIT: it copies the in-memory executable code from the instructions at these goto labels to form basic blocks in an executable CFG. That gets you 1.6x speedup on those benchmarks, but it's a lot more work.
I really wish Rust/stdlib had been built around a good async io story. Right now it just feels neglected "because the crates ecosystem can deal with it". I might be wrong here but it always seemed to me that Rust was built to replace C/C++ in critical infrastructure like Firefox, Nginx, Redis, etc. Basically critical network dependent infrastructure. With respect (because I understand the difficulties that come with…
Well, and again, it doesn't implement the entire web platform, but Servo is already showing significant speed gains, even without AIO. It's really more useful for servers than clients. It's important to remember that IO is truly a library concern in Rust. 1.0 means the language is stable, but there's still tons of libraries to build on top of that language. Holding back the language itself for a library that, while i…
In this particular context I believe using Servo as an argument is misleading. And actually its not just about "doesn't implement the entire web platform". Servo gains all of its performance wins from parallel rendering. A very effective but entirely orthogonal optimization. Just because one optimization far outweighs the performance wins of another optimization doesn't mean the other should be neglected entirely. Also, Servo's benchmarks run a relatively light workloads, i.e. one page at a time.
The argument might be similar to using benchmarks for a parallel web rendering engine (a Servo-like) in Go. It would probably have similar median latencies to Servo. And Go may even scale out better if tabs were sandboxed in goroutines instead of processes. However, ofcourse unlike Servo it would have a higher variance/p90/p99 latencies because of the GC. P.S. I'm not a big fan of Go I was just using it to try and bolster my argument that Servo's current benchmarks shouldn't be used as an argument against async io prioritization. Actually, side note, I would love to hear more flaws about building a Servo-like in Go.
That's about what I expected, contrary to the 2-4x times speedup mentioned above. Still, I can imagine in isolated cases you really would get a better number than that 10%. So, for code where performance is super important and where the effort of the optimization and lack of transparency is outweighed by the performance boost this makes sense.
Yes, that 10% is an average over seven benchmarks. The numerical one gets a 25% speedup, the one with a bunch of exceptions doesn't benefit at all. The funny thing is, if you're interested in performance, you're probably going to be writing a JIT, so this optimization is really just a stop-gap measure. In fact, the inline threading I mentioned is a kind of cheap JIT: it copies the in-memory executable code from the i…
> The funny thing is, if you're interested in performance, you're probably going to be writing a JIT, so this optimization is really just a stop-gap measure.
Exactly. And stop-gap measures are fine if and when they're followed up by a proper solution. Unfortunately stop-gap measures tend to be a lot more permanent than originally intended in practice.
Metaprogramming to the full power sounds like Lisp. It doesn't have goto.
> Metaprogramming to the full power sounds like Lisp. It does, yes, although many Lisps got a pretty limited backend for this sort of things. My preferred metaprogramming environment must have a fallthrough mode for allowing generating low-level code where Lisp semantics is not sufficient. Rust seems like a very good target platform in this sense, so the lack of goto really hurts. > It doesn't have goto. Of course th…
> Of course they do (tagbody in Common Lisp, for example). And when they don't, it's often relatively easy to add one.
I was wrong, however it is much more limited than the goto everywhere from C, as where the labels are located is clearly defined in the tagbody and not in every possible statement.
What about things that Rust shipped without that should have been included?
A requirement to stick #version 1.0 at the top of code files so we know which version they were intended to be compiled with, such that in future we can introduce breaking changes into version 2.0 and still have support for compiling legacy 1.0 applications. Seriously, nearly all data storage formats we use today have some kind of version number in them - why are we treating code as dumb text rather than interesting…
That probably fits better in Cargo.toml, where it's also a lot less work to add later.
If Rust misses 'goto', it is not suitable for translating SSA into it, which most compilers natually produce (also for LLVM, obviously). I.e., it is not suitable for being used in a compiler backend. Here, it can never fully replace C. 'goto' should not be daemonized, we know better today.
Rust only targets LLVM IR, so its chances of fully replacing C are nil anyway.
Nothing about the language itself requires targeting LLVM IR, that's just what the (currently only) implementation targets.
But either way, what about targeting LLVM IR makes it unable to replace C? Portability?
Which is actually a useful feature in some obscure optimizations, like this fast (approximate) square root: float half_r=r*0.5F; union { float y; int32_t i; }; y=r; i=0x5f375a86-(i>>1); y=y*(1.5F-(half_r*y*y)); return y;
That hasn't been an optimization for 15 years now. Fast approximate inverse square root is a builtin operation on most FPUs-- on x86, it's RSQRTSS, which tends to be the same cost as a floating point multiply. (for Haswell, it has a 5 cycle latency, and 1 cycle reciprocal throughput)
Interesting, though not useful unless there's a good way to access it from portable C/C++. An __asm__ section or equivalent would work, but would only be useful on a particular CPU -- and different compilers use different syntax for embedding assembly, so that's not ideal either.
But where I'd more likely use that optimization at this point is on Arm or ATmega processors. ARM doesn't seem to have an approximate inverse square root, based on a quick check, and ATmega are frequently still stuck with software floating point, so I'd hardly say that the optimization is dead.
Come on, even that flag's name is ridiculous. They basically say, for example, that writing camel case, which is the preferred style in most of the projects I've seen, is bad style. Do they like being unnecessarily antipathetic? People think about their personal preferred style for years, and they have very good reasons for choosing them. And in _many_ cases, it's exactly the style that's called bad by Rust's creator…
In some cases skirting style can be harmful (e.g. in match statements there's an ambiguity with enum variants and variable bindings that is not an issue because of the style lints). But I get your point. I think people would be open to that naming change if you file an issue.
Yes, you're right, of course.
Maybe I could at least try, yes. I mean... It's kind of silly, I know, but that would already change the way I look at Rust.