On Sat, Jan 11, 2014 at 12:15 AM, Lee Braiden <[email protected]> wrote: > This may be go nowhere, especially so late in Rust's development, but I feel > like this is an important, relatively small change (though a high-profile > one). I believe it could have a large, positive impact in terms of > targeting new developer communities, gaining more libraries and > applications, giving a better impression of the language, AND on performance > and futureproofing. > > However, a lot of people who are interested in performance will probably > baulk at this, on first sight. If you're in that group, let me encourage > you to keep reading, at least until the points on performance improvements. > Then baulk, if you like ;) > > Also, I said it in the post as well, but it's late here, so apologies for > any readability / editing issues. I tried, but sleep beckons ;) > > > > http://blog.irukado.org/2014/01/an-appeal-for-correct-capable-future-proof-math-in-nascent-programming-languages/ > > > -- > Lee
> The wrongness of float There is no lossless implementation of real numbers on a computer. You assume arbitrary precision floating point can cover every real number, but there's no such thing. Arbitrary precision means you can choose the precision used by the numbers. It's certainly no replacement for hardware floating point because it's many orders of magnitude slower. You may not understand IEEE754 floating point arithmetic, but it's certainly not *wrong*. > The wrongness of machine ints Big integers are many orders of magnitude slower than hardware integer arithmetic. It's not a replacement for it, but rather an alternative when you need a larger range. You still need to validate inputs because it's very easy to go out-of-memory, and that's going to bring down the whole process or even other processes on the system. > For those looking to reject this idea on the basis of optimisation: consider > that abstracting away from 32-bit integers or 64-bit floats, or 256-bit ints, > can potentially lead to better optimisation, if the compiler can then figure > out that it’s on a 256-bit machine (or indeed, is targeting a 256-bit GPU) > and is free to optimise accordingly. This isn't how hardware works. Smaller floating point numbers are faster than higher precision, because they're smaller. An array of 32-bit floating point numbers will always be half the size as the same array of 64-bit floating point numbers. Double the amount of data can fit into the layers of caches, and you can fit twice as many into SIMD registers so there's double the amount of theoretical throughput. > real becomes, not a 32-bit float (as I understand it currently is), but what > it sounds like: a real number, covering all numbers in the real number range, > using an arbitrary precision type. Rust doesn't have a `real` type. It has `f32` and `f64`, which are an explicit opt-in to IEEE754 binary floating point. If you don't want this, you don't have to use them. Anyway, covering all numbers in the real number range isn't possible. You can have the user pass the desired precision in the constructor and then handle two inputs of varying precision in a sensible way. > int is not (misleadingly) a machine word, but represents what it sounds like: > the entire range of integers, using a bigint type. The Big int type in extra > would probably be fine, if it were optimised more. I noticed that there were > pull requests for large performance improvements in bigint, but they were > rejected for lack of comments. I suspect, if it where given its rightful > place as the only fully capable integer type in the libraries, then it would > rapidly gain performance through patches, too. A pointer-size integer type is required. A big integer type cannot be implemented without library support, and will always be significantly slower than hardware integer types. A Rust big integer implementation is not going to be competitive with libraries like `gmp` for at least a decade. An enormous amount of work is required to implement the whole range of algorithms with better asymptomatic performance, then optimize with per-platform assembly and figure out the heuristics for selecting the algorithms. Placing a huge performance burden on all Rust code and pushing it far behind Java in performance is not going to result in a fantasy world where big integers are the same speed. > Range checking be implemented in debug and optimisation compiler modes, to > support the above, and for the general (ada-like) safety benefits that > range-checking of numbers would provide. If it’s REALLY such a > compilation-speed turn-off, it could be enabled with specific compiler flags. Range checking also results in significant performance overhead. Two's complement arithmetic is also often desired, especially in cryptography and hashing algorithms. Checked overflow is already provided in the standard library and alternate types handling overflow in a different way than two's complement arithmetic could be added. Pretty much the only useful thing here would be implementing an enum using a hardware integer for small values, and overflowing to a big integer. > Rust compilers can optimise int to i32 etc. _automatically_, iff it knows > there are no problems doing so, because of the number ranges involved in > calculations. This isn't going to happen in the real-world. Compilers are not magic, and can't just go changing the size of a type across the program and somehow figure out where all of the pointers go. > Likewise, f64, etc. are considered optimisations of real, and can either be > optimised by hand, or — potentially, if the compiler work is done — > automatically. Real number precision is always going to be a compromise. There is no such thing as perfect precision, and Rust doesn't need to choose a default. The only time I can imagine you would be able to lower the precision is if someone casts a 32-bit floating point number to 64-bit, performs an operation and then stores it back as a 32-bit number. It's not going to scale. > equality comparisons are accurate for math by default They are already accurate. > number range checking would be available, either by default or as an optional > compiler feature / optimisation flag It's already available and you can write an integer type with checked overflow. The performance is not impressive, and there's nothing Rust can do about it. It's outputting the checked overflow intrinsics and you can choose to handle the overflow flag however you wish. > New x86_64 CPUs will (may already) implement decimal types in hardware — in a > way that’s compatible with C++’s new decimal types AFAIK this isn't implemented in hardware. Anyway, IEEE754 decimal floats have the same caveats as binary floats except that they won't have lower precision than literals written as decimals. > Slower math by default. A compiler flag could override this, or people could > manually specify a faster f32/f64/i64 type, for example, if they care. I do > not think this is a significant problem. This isn't a significant problem? Rust is a systems language, and as a systems language it is going to expose the fast low-level primitive types. If it doesn't offer C level performance, then it's not a very useful language. Brushing aside performance issues by pretending optimizing compilers are omnipresent, magical tools does not work. The language you're looking for isn't Rust, because you don't care at all about performance. # What can actually be done? I have already opened an issue about removing the fallback of integer literals to `int` when another type can be inferred. If there's no fallback, then it's only a matter of adding support for generic literals like Haskell to have all integer types as first-class citizens. Rust doesn't need a default integer type. It doesn't need to make any choices about this at all. It can offer 32-bit, 64-bit and eventually 128-bit IEEE754 floating point numbers. It can offer 8-bit, 16-bit, 32-bit and 64-bit variants of two's complement arithmetic integers. It can offer big integers, rational numbers, arbitrary precision binary floats and arbitrary precision decimal floats. You can use the suitable tool for the job without burdening everyone with significant performance overhead and turning Rust into something that's not a systems language. _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
