Live data from Hacker News

The Road to Rust 1.0

blog.rust-lang.org

241–248 of 248 posts

Re: The Road to Rust 1.0

#241
post #165

Earlier quoted context omitted.

For small strings, a copy is not only faster but more multithreading friendly. Keep in mind that on a 64-bit architecture a view is at least 16 bytes large and that small strings can be copied to the stack resulting in better locality and reduced memory usage. Last but not least, with copy elision, your temporaries might not even exist in the first place. Example: std::string data; // ... auto str = data.substr(2, 3)…

I don't think copy elision[1,2] means what you think it means, it simply allows the compiler to avoid e.g. allocating a new string when returning a string, or avoid allocating a new string to store the result of a temporary. That is, copy elision allows std::string str = data.substr(2, 3); return str; to only allocate one new string (for the return value of substr), instead of two. There's no way the compiler can get…

Yeah my example for copy elision sucked, but that doesn't mean it cannot play in favor when you work by value.

Sharing is only multithreading unfriendly if there's modification happening, modification of textual (i.e. Unicode) data is bad practice and hard to get right

Read-only access to data indeed scales "infinitely" on modern architectures.

No, a string_view points into memory that already exists,

Yes. Right. How do you store that? You need at least one pointer and and an int or two pointers. That 16 bytes. Memcpy for a couple of bytes is very quick when it's stack to stack thanks to page locality.

Also, if you are using pointers you will have aliasing issues which will have an impact on performance. If you work by values you allow the compiler to optimize things better.

For small strings string view are just dumb and "most of the time" strings are very small.

To give a better example of why working a string view is both a bad idea and dangerous, it's as if you said "I don't want to copy this vector, therefore I will work on iterators". That's obviously a bad idea.

Re: The Road to Rust 1.0

#242
post #165

Earlier quoted context omitted.

I don't think copy elision[1,2] means what you think it means, it simply allows the compiler to avoid e.g. allocating a new string when returning a string, or avoid allocating a new string to store the result of a temporary. That is, copy elision allows std::string str = data.substr(2, 3); return str; to only allocate one new string (for the return value of substr), instead of two. There's no way the compiler can get…

Yeah my example for copy elision sucked, but that doesn't mean it cannot play in favor when you work by value. Sharing is only multithreading unfriendly if there's modification happening, modification of textual (i.e. Unicode) data is bad practice and hard to get right Read-only access to data indeed scales "infinitely" on modern architectures. No, a string_view points into memory that already exists, Yes. Right. How…

> Yeah my example for copy elision sucked, but that doesn't mean it cannot play in favor when you work by value.

Not just sucked; it was entirely wrong. Copy elision is not related to std::string vs. string_view. Even with copy elision turned up to 11, returning a std::string will be more expensive than a string_view.

> How do you store that? You need at least one pointer and and an int or two pointers. That 16 bytes. Memcpy for a couple of bytes is very quick when it's stack to stack thanks to page locality.

I was very careful to cover exactly this in my comment.

Computing the memcpy is strictly more work than creating a string_view, since you need the information that is stored in a string view (i.e. pointer and length) to call memcpy.

Furthermore, the 'stack string' is actually stored contained inside a std::string value, which is larger than 16 bytes. There is no way that returning a string_view causes higher memory use at the call site than returning a std::string. (If you're complaining that it forces old strings to be kept around, well, you can always copy a string_view to a new std::string if you need to, i.e. a string_view can do the expensive 'upgrade' option on demand.)

Here's the quote from my comment above:

> a small string copied on to the stack will be part of the string struct, which is at least 3 * 8 = 24 bytes: a pointer, the length and the capacity. Also, a memcpy out of the original string is always going to be more expensive than just getting the pointer/length (or pair of pointers) for a string_view, since the memcpy has to do this anyway.

> Also, if you are using pointers you will have aliasing issues which will have an impact on performance. If you work by values you allow the compiler to optimize things better.

You do realise that a std::string contains pointers and so on inside it? Furthermore, the small string optimisation (copying to the stack) means every data access to a std::string includes an extra branch.

> For small strings string view are just dumb and "most of the time" strings are very small.

So instead of just having a cheap reference into a string you're happy with the overhead of a function call (memcpy) and a pile of dynamic branches? I wouldn't be surprised if the branches are the major performance burden for std::string-based code that is processing a pile of substrings of some parent string. In this case, the data from the string_views will normally be in cache anyway (i.e. it will've been recently read by the function that decides who to slice into the string_view).

> To give a better example of why working a string view is both a bad idea and dangerous, it's as if you said "I don't want to copy this vector, therefore I will work on iterators". That's obviously a bad idea.

It's not obviously bad to me. In fact, it seems very reasonable to work with iterators rather than copying vectors (isn't that exactly what the algorithm header does?).

If your problem is that it is unsafe and hard to avoid dangling pointers etc, that's just a fundamental problem of C++ and is unavoidable in that language. One fix would be to use Rust; it handles iterators and string_views safely.

Re: The Road to Rust 1.0

#243
post #232

Earlier quoted context omitted.

With 1:1 scheduling, how do you limit stack size to something reasonable (a few kB per thread), which is necessary when you need to launch tens of thousands of threads?

If you know you only need a small amount of stack size, you can set the stack size to be small via the task builder: http://doc.rust-lang.org/master/std/task/struct.TaskBuilder....

Thanks for the link. But what if I don't know the stack size in advance? I guess the model with a stack that starts small and grows on demand is only possible with M:N scheduling, not with 1:1 native scheduling?

Re: The Road to Rust 1.0

#244
post #14

Earlier quoted context omitted.

Curious to hear more about language-specific (though OS-agnostic!) package management systems. IMO composer is the best thing ever happened to PHP, Ruby gems are huge, Python eggs also make a very useful ecosystem. OpenSUSE's Open Build System would be great to ship independent packages, but those are again heavily tied to Unices, hence leaving other platforms behind.

> Curious to hear more about language-specific (though OS-agnostic!) package management systems. As far as I can tell, one of the main justifications for most language package management systems is "we also run on Windows/OSX, which has no package management, so we'll invent our own". As a result, users of systems that do have sane package management get stuck with multiple package management systems, one for the dis…

Most of the unix package management systems are not really that good for development: they don't support sandboxing, or non-root installation/execution, or don't support the right kind of versioning, or don't support multiple versions of a library, or some other issue.

The only existing system that I might trust enough for this kind of thing Nix, and at least for Haskell it is a pretty solid alternative to their language-standard package manager. Unfortunately, its popularity is way lower then stuff like apt or yum which are pretty shitty for development compared to something like pip or cabal.

Re: The Road to Rust 1.0

#245
post #169

I used to describe my preferred family of languages as: - C when I absolutely had to (kernel/modules/plumbing). - Python for scripting and broad accessibility. - Haskell when I had the choice and I knew everybody who would work on the project. I was skeptical of Rust when it first came out, due in large part to the many different kinds of pointers it originally had, many of which involved significant manual memory ma…

>Disappointing to see yet another language-specific package management system (Cargo), though. As a packager in a Linux distro, I'm disappointed every time somebody tries to cram in PL-specific packages inside distro packages.

Interesting, how do you get around it, when those packages are depended upon by user facing software?

Re: The Road to Rust 1.0

#246

Earlier quoted context omitted.

I just don't understand why there has to be a tradeoff. I just don't get why the compiler should decide on such a large thing, instead of letting the programmer do it. One can always be more explicit if one feels they're getting value from it. If someone wants to write a bunch of terse code, why stop them? Does the compiler gain a large benefit from not having to include this feature? Who loses by allowing users to d…

> Who loses by allowing users to do what they want? Everyone else who looks at your code who would have preferred them. I dabble with both Go and Haskell, and this seems like the best of both worlds: from Go they enforce a uniform standard across libraries, coworkers' code, etc, and from Haskell, they're adopting the philosophy that "types are documentation". I, too, would be a little annoyed at documenting lambdas,…

It seems you could look at unannotated code with a tool which gives you inferred annotations.

Re: The Road to Rust 1.0

#247
post #56
post #49

Earlier quoted context omitted.

> Disappointing to see yet another language-specific package management system (Cargo), though So what is the solution to have portable packages for: - RPM systems - Debian systems - tarball systems - Pkg systems - MSI systems - Mainframe OS - Embedded OS - Aix/HP-UX/Solaris package systems - ...

The goal of the [nix]( http://nixos.org/ ) project is to solve this, and every time anyone brings up a package manager on HN, someone has to mention nix. The reality is that nix is really nice, but isn't any better than making a new package manager until it has wide adoption, so no one is using it.

How would (or how does) Nix deal with windows anyways? Are it's abstractions portable enough?

Re: The Road to Rust 1.0

#248
post #206
post #127

Earlier quoted context omitted.

Iterator invalidation, dangling references, and use-after-move are all essentially the same thing---references outlasting their owner---no need to multiply the issues. Buffer overflows are an issue, yes, unavoidable due to the C legacy. On the other hand, it's somewhat ironic that you point to overlong shifts as a C++ problem when Rust has the exact same behavior. What does this function return? pub fn f(x: uint) ->…

Well, people tried that with D. Didn't catch on.

It caught on a little.
Post reply on HN