
Rust 1.24 - steveklabnik
https://blog.rust-lang.org/2018/02/15/Rust-1.24.html
======
kibwen
Incremental compilation! And it's only going to incremental-er from here, as
the compiler learns how to cache more and more sorts of interim artifacts to
avoid redundant work. Though I think the wording in the OP is a bit off:

 _> Historically, the compiler has compiled your entire project, no matter how
little you’ve changed the code._

This isn't quite correct. When you change the code in a given library, it has
historically recompiled that entire library, and all libraries that depend on
that library. But the compiler has never recompiled any libraries that were
_deeper_ in the dependency chain: if you have crates foo and bar, and bar
imports foo, and you change the code in bar, foo was not recompiled.

Looking towards the future, I'm most excited about the prospect of using SIMD
on stable Rust, which looks to be coming this year: [https://github.com/rust-
lang/rfcs/pull/2325](https://github.com/rust-lang/rfcs/pull/2325)

EDIT: Also worth mentioning is that Rayon (an official Rust library providing
easy data parallelism) just reached 1.0 today, which is an important milestone
in Rust's march towards ecosystem stability: [https://github.com/rayon-
rs/rayon](https://github.com/rayon-rs/rayon)

~~~
yazaddaruvala
Have there been any thoughts around making the compiler something akin to a
stateful server with an embedded datastore for the caching rather than using
the filesystem?

~~~
AceJohnny2
What would be the benefit of this approach over using the filesystem?

~~~
azdle
I'd imagine it would be a benefit where, let's say, every project has
`byteorder` in its dependency tree somewhere. If you had a local, stateful,
build server that processes every build on your machine, you could re-use the
object file from the last time you compiled that library regardless of if it
was for this project or not. That's probably not a big gain for just
`byteorder`, but if you multiply that by many libs or take into account some
of the much bigger ones it could make quite a difference in build time. Even
"first" build time for new projects you're building.

IIRC, some group in mozilla has already has something working that works like
ccache that works (or rewrote ccache to work) with compiling rust. (Which I
think is what steveklabnik is alluding to in his neighboring comment.)
Although I guess that might only work within a single code base, not sure
about that.

~~~
steveklabnik
You're thinking of
[https://github.com/mozilla/sccache](https://github.com/mozilla/sccache) which
is not _quite_ the same thing.

------
dsymonds
Good to see rustfmt arrive.

Sad that it is configurable, though. The biggest benefit of its predecessors
such as gofmt is that they are _not_ configurable, leading to a much more
uniform formatting style and avoiding endless discussions about whitespace
layout.

~~~
kibwen
I don't agree. There is a default configuration, and that configuration is
very good (I've been following the process of nailing it down, and IMO it's
been done very tastefully), and is the formatting used by official Rust
codebases, lending it the weight of authority. I have no reason to configure
it to do anything differently. But I also have no reason to forbid anyone else
from formatting code as they please. What's the possible harm? If you're on a
team, and you want code uniformity, you require the default configuration. If
you're worried about pulling some random code and having it use {tabs|spaces}
instead of {spaces|tabs} (which, btw, is, without hyperbole, the dumbest
argument in the entire human history of programming) then you set your editor
to run rustfmt on files before opening them.

The gofmt argument isn't the final word here. There's plenty of Go users who
don't like gofmt's style, so they just don't use gofmt. It's easy to imagine
other users who don't like gofmt's style, and don't like being pressured to
use it, so they just don't use Go at all. How is that any better than just
having a configurable tool with sane defaults? It's one thing for a tool to be
opinionated; it's another thing entirely to be dictatorial and stubbornly
inflexible.

~~~
coldtea
> _But I also have no reason to forbid anyone else from formatting code as
> they please. What 's the possible harm?_

Obviously the proliferation of coding formatting styles. It's not we didn't
have "official styles" and formatting tools before for other languages.

The greatness of gofmt, and what people love it for, is how it killed all
other options.

~~~
pjmlp
Not sure if it was actually that, many don't seem even aware of _indent_ ,
whereas I used to work in places that executed it as CVS pre-commit hook.

------
fafhrd91
tokio-minihttp is 1 in plaintext benchmark in TechEmpower Web frameworks
benchmark

[https://www.techempower.com/benchmarks/#section=data-r15&hw=...](https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=plaintext)

~~~
Thaxll
I wouldn't post Rust benchmarks in here it's behind Java in every scenarios.

~~~
steveklabnik
It's not in every scenario, notably, the plaintext one.

One reason why things are behind in some of the other scenarios is because our
database driver stuff is synchronous at the moment, and that _really_ hurts on
these benchmarks. We'll get there!

------
eslaught
> If you’re a fan of str::find, which is used to find a given char inside of a
> &str, you’ll be happy to see this pull request: it’s now 10x faster! This is
> thanks to memchr.

Wait, how is that safe? Aren't Rust strings UTF-8? Even if you search for a
ASCII character, couldn't it conflict with the second byte of a different
unicode codepoint?

~~~
Felk
If I'm not wrong, UTF-8 continuation bytes always start with binary 10, where
ASCII always starts with 0 and multi-byte starts start with either 11 (2
bytes), 111 (3 bytes) or 1111 (4 bytes)

~~~
Manishearth
That doesn't solve the problem of searching for multibyte character AB and
finding multibyte character CB instead :)

Or, searching for multibyte character ABB (like U+A041 YI SYLLABLE PA) and
finding the first "B" instead of the second "B".

Sadly there's no memchr for consecutive sequences of characters.
memchr2/memchr3 let you search for multiple needles in the haystack, not a
bigger needle.

~~~
comex
There’s memmem...

~~~
burntsushi
memmem is substring search. You could use it for char search, but does memmem
know about UTF-8? If, say, memmem uses memchr internally in a skip loop and it
happens to look at the first byte in the UTF-8 encoded codepoint, then it is
going to perform _a lot_ worse in most cases involving the search of text that
is in a language other than English (because it will wind up searching for a
very common byte).

Or maybe memmem does something else clever for shorter needles. Dunno. Best to
benchmark it. But it's not an obvious win a priori.

~~~
Manishearth
I do want to see if a 2/3/4-byte memchr can be written that uses the same
bitmasking as regular memchr but extended to more bits (perhaps via SIMD).

That would be pretty neat.

~~~
burntsushi
Yeah that's what I was thinking memmem might do. But yeah, I bet you that
Hyperscan has a vectorized algorithm for this somewhere. It is just a matter
of finding it.

------
talson
Can someone sell me on using rust over python? I am just gernerally curious as
to the advantage beyond rust being compiled.

~~~
kzrdude
When I use Python I miss Rust's enums, the pattern matching of those enums,
and the static types that help refactoring (the compiler spots where one
change has knock-on effects in the rest of the project..).

Especially how Rust enums and structs make it easy to define new types to
guide your programs are a highlight for me.

I don't think Rust is better than Python for every task. Python is a lot
simpler if you can get something done with its built in types (dicts, sets and
lists). Python's dynamic types are also a great benefit for some tasks, where
Rust's dynamic dispatch support is very limiting.

Crazily, handling dependencies and building a project is way easier in pure-
Rust than pure-Python since it's standardized.

~~~
Rotareti
_> Especially how Rust enums and structs make it easy to define new types to
guide your programs are a highlight for me._

In recent versions Python got some nice improvements in this area, with the
new way of creating _NamedTuples_ , _Data Classes_ and the _typing_ module. I
wrote a stackoverflow answer recently that sums it up, if anyone is
interested:

[https://stackoverflow.com/a/45426493/1612318](https://stackoverflow.com/a/45426493/1612318)

~~~
sidlls
Those artifacts in Python don't really compare with what the parent laments.
Rust's sum types are one of my top reasons for preferring the language.

------
dhbradshaw
Satisfying to see rustfmt hitting stable, even if only in preview form.

~~~
deadprogram
Agreed!

------
clarkmoody
Incremental compilation turned on by default :-)

~~~
jolmg
Hmm... when I read that, I got excited thinking it would be like Common
Lisp's, where the idea is to incrementally compile in changes to a _running_
program, to the effect of being able to see the effects without having to
restart it. This just sounds like what Makefiles do, but at a sub-file/AST
level.

~~~
steveklabnik
It's an overloaded term, it means both, basically.

Your analogy to Makefiles is right in a big-picture sense. In the small, it's
different, but you've got the big idea correct.

------
XR0CSWV3h3kZWg
Is rustfmt fast enough to reasonable be put on a save hook?

~~~
steveklabnik
I went into one of my projects and did a `cargo fmt`, took 2.2 seconds. Dunno
if that's within your tolerances or not. I personally have CI check it, rather
than on save.

~~~
RX14
I know it's fairly pointless performance bashing but I just couldn't stop
myself :)

    
    
        # In the crystal-lang/crystal repo
        $ find . -name '*.cr' -print0 | wc -l --files0-from=- | tail -n 1
        252745 total
        
        $ time bin/crystal tool format
        Using compiled compiler at `.build/crystal'
        bin/crystal tool format  0.62s user 0.04s system 106% cpu 0.625 total
    

and only 48ms to formal the longest file in crystal (the parser)!

Performance makes little practical difference as long as formatting a single
file is fast enough to be on-save, but it does highlight the very interesting
way that the crystal formatter is implemented. I'm not sure how rustfmt is
implemented but crystal's formatter parses the file into the AST, and then
does a single visitor pass of the file, in order, with a lexer in tow. It then
basically reconstructs the entire file from scratch using the data both from
the AST and the lexer (the AST visitor pass and lexer position have to be kept
in sync). And surprisingly enough, this doesn't even make the formatter "too
strict" in the way that it wipes out all existing style information as one
would expect. It's a really cool - if a little messy - tool and one of I think
my favorite parts of crystal (it doesn't have any config options either).

------
nikkettt
I recently rewrote a few small c scripts in Rust, (mostly to try the language
features), the experience was really good. I don't think I will ever start a
new project in C again.

------
deadprogram
rustfmt looks very cool. I look forward to using that partcular feature.

------
xstartup
Is Helix still best Ruby-Rust way?

