10 ms·
Why can't we have a language easy to read and maintain but also have the speed of C?
by ano88888 4y ago
Why can't we have a language easy to read and maintain but also have the speed of C?
- killingtime74 4y agoTranspile to C? Zig or Rust?
- skohan 4y agoYeah I think Zig in particular is trying to be just exactly a "better C". I don't know if transpiling will get you there, because for instance if you're transpiling a dynamic language, you're going to have to output C that is essentially emulating all those dynamic language features, so it might be faster than say, the original Python, but it's not going to be as fast as a pure C implementation.
- bruce343434 4y agoYou can't just "transpile to C" to get "C speed". C speed comes from low overhead. Naive transpilations will just include that overhead, like garbage collection or many layers of pointer indirection, but written in C. The unsavory answer is that you must use less abstractions if you want fast code. Compilers just aren't good enough to compile all the abstractions away.
- pjmlp 4y agoThat includes C versus modern CPUs.
- dahfizz 4y agoThe CPU is the CPU regardless of what language you are running on it. C will still give you the best performance on a modern CPU. If anything, C has an even bigger advantage on modern CPUs because it has easier access to things like vectorize/SIMD intrinsics. It is also easier to tweak your data dependencies to help the branch predictor.
- pjmlp 4y agoNope, those are language extensions not defined by ISO C. Any language can have such intrinsics as extensions, for example D, Rust, C++, Swift, .NET, Java (as preview).
- kaba0 4y ago> If anything, C has an even bigger advantage on modern CPUs because it has easier access to things like vectorize/SIMD intrinsics. It is also easier to tweak your data dependencies to help the branch predictor. Have you seen the ridiculously complex optimizations that C compilers do to maybe turn some shitty for loop into vector instructions? C is terribly bad fit for this use case and hardware tries to get closer to C than the reverse. C++, Rust but even C# and Java has much better SIMD support than C has. EDIT: It really doesn’t help C (and some of the listed languages as well) that they are very imperative. SIMD is exactly the place where pureness and some form of FP is much better at allowing these kind of optimizations (a map of a pure function can be “trivially” optimized into vector instructions, while it is really hard to decide whether this for loop is safe to convert, and it is really up to the heuristics of the compiler. A bit of rearrangement can cause a failure to optimize, resulting in a huge drop in performance)
- mhaberl 4y ago> Transpile to C? If you transpile something to C it does't mean it will be fast. You can write slow C code (or transpile something to C that will be slow). The compilers are not the issue here.
- gpderetta 4y agoIn fact it might be slower than actually targeting a proper compiler intermediate language.
- foerbert 4y agoWho says we don't? I think I'm past-due for my regular Ada plug, so uh, here it is.
- jakobnissen 4y agoRust is that if you keep the code simple without too many trait objects and macros and type magic. But then it becomes even more constrained than it actually is. It'll also be boilerplate heavy and hard to write. Julia is fast, easy to read, and easy to write. But it's not easy to maintain. There is a direct tradeoff between dynamism on one hand making things easier to read/write and static enforceability on the other making it easier to maintain.
- deleted 4y ago[deleted]
- flohofwoe 4y agoIt's not "the C part" that makes code run fast, but memory access patterns. C just happens to not get in the way between the coder and the machine when it comes to explicit control over memory layout. In the late 60's and early 70's this was probably an "accidential feature", but with the widening CPU/memory performance gap it turned out that later languages (from the late 90's and early 00's) had bet on the wrong horse by trying to abstract memory away. More recently this trend is reversing again and plenty of C alternatives are starting to appear with explicit control over memory layout (Zig, Nim, Odin, Rust, ...).
- skohan 4y agoDoesn't Rust mostly abstract the memory management away as well? It tends to be low overhead, and has sensible defaults with respect to memory management, but it's built around RAII and for instance if you use a lot of reference types as far as I know there's nothing keeping you from having fragmented memory the same way you would with another high level language. I know Rust also offers arenas and other purpose built tools for more optimized allocation strategies, but Rust doesn't seem like the language you would reach for if your number one priority is memory performance. It seems like there is a necessary trade-off between truly top-end memory performance and memory safety.
- flohofwoe 4y agoWell yeah, you can write slow code in any language if you don't think about memory layout ;) I see Rust roughly in the same bucket as C++. You can abstract the details of memory management away - which mostly also means giving up control over how things are arranged in memory - but if needed the low level explicit memory management features are there.
- skohan 4y agoI guess the difference is that C++ still gives you pretty much direct access to memory (i.e. pointer arithmetic). Rust tries very hard to keep you at arms length from the actual memory as a rule, and forces you to work through a safe abstraction unless you use an escape hatch.
- mcbuilder 4y agoHaskell has an elegance, and can be written as simply as C. Usually fast enough, and can be optimized as well. The downside is that you will be sucked into a rabbit hole of academic type theory and wonder how best to express your system as a Free Monad instead of bashing it out like any sane C programmer. Just kidding, someone already figured out those hard parts for you, you just forgot to browse for it on Hackage.
- bigDinosaur 4y agoIt's a fair criticism of Haskell that you can fairly easily blow up your time/space complexity without realising it though. I think in many ways it's better but Haskell specifically demands a lot even for a functional language.
- meheleventyone 4y agoZig!
- paskozdilar 4y agoGo fills that spot for me. I've done video4linux stuff in Go, and passing an unsafe.Pointer to a Go struct in an ioctl() worked fine, which tells me that Go structs are isomorphic to C structs. Even though Go has garbage collection, it allocates everything it can on the stack, so only long-lived shared-between-goroutines objects are subject to garbage collection. Go abstracts concurrency, completely removing all concurrent features from a language except for the "go" keyword (that launches a goroutine - which is basically a tiny virtual thread), channels (which are selectable queues) and "select" keyword that waits for the first "input" from a static set of channels.
- skohan 4y agoGo strikes me as one of the best "good enough" languages we have right now. You're not going to do HPC in Go, but it's performant enough to run circles around a lot of high level languages and dynamic languages. It abstracts away the stuff that's super error prone about manual memory management, and it's so brutally simple that it's hard for one of your colleagues to write code you're not going to be able to understand. There's a few features that could improve it, like proper ADT's, and it's a bit lacking in expressiveness for me to choose it for personal hobby projects, but I would recommend it any time for general-case professional software development.
- kaba0 4y ago> but it's performant enough to run circles around a lot of high level languages and dynamic languages It ain’t running circles around any managed language, with perhaps the exception of Python. C#, Java, JS all have comparably good performances, sometimes much better - e.g. when GC can’t be avoided.
- bheadmaster 4y agoGo is in my experience significantly faster than Java, and uses an order of magnitude less memory for equivalent functionality. If you have any data (or better yet, benchmarks I can run on my own machine), I'd very much like to see some hard numbers.
- anfelor 4y agoOcaml 5 and Koka (https://koka-lang.github.io/koka/doc/index.html https://koka-lang.github.io/koka/doc/index.html) can get quite close to the speed of C...
- xigoi 4y agoUnfortunately, Koka doesn't seem to be ready for general-purpose use…
- enriquto 4y ago> Why can't we have a language easy to read and maintain but also have the speed of C? Fortran is fine. Also lua (using the luajit interpreter you get really close to C speed) and julia (except for the atrocious startup time).
- pjmlp 4y agoPascal dialects, Modula-2 are of a similar age, while other like JOVIAL are a decade older but they did not come with a very big killer feature, an OS like UNIX. Then there were BLISS, Mesa and PL/I, but the OSes that made use of them lost to UNIX, so. With exception of Mac OS, written in Object Pascal and later ported to a mix of Object Pascal and C++. Having said this, plenty of alternatives with AOT compilers exist nowadays. The only thing C has going for it, is historical weight, UNIX/POSIX ecosystem, and some domains that are closed to any alternative suggestions, due to tooling or cargo cult against alternatives.
- thorncorona 4y agoJulia is that for a lot of academia + mathematics based code.
- xigoi 4y agoWe can. https://nim-lang.org/ https://nim-lang.org/
- jayp1418 4y agoAda Programming Language
- FeepingCreature 4y agoD as well, though only (like Rust) if you keep the traits and template stuff low. The nice thing about D for me is that you can generally banish the unreadable metaprogramming code to a library.
- deleted 4y ago[deleted]
- Banana699 4y agoBecause "easy to read and maintain" is about humans, and "speed of C" is about machines, and there is a vast gulf between the 2 that always force you to compromise in one or the other to get the 2 together, and usually both. Code being easier to read and maintain is a function of how close it is to human semantics. The more the algorithm is presented in terms and notations humans like and find familiar, the easier. Code being performant is a function of how close it is to machine semantics, the more the algorithm is presented as steps that the machine likes and finds familiar, the faster it will run, as the machine is doing less to execute each step. There is a fundamental tension between the 2, even if compilation from high level languages might, at first glance, give us the illusion that we can have both. We can't, not in general. We can only do it for a class of human semantics that C++ folks call "Zero-Cost Abstractions", the set of abstractions that can be completely erased without a trace by the time you get to the executable. But otherwise, there is a fundamental cost to making code more readable by humans: making it less readable by the machines that will execute it. This is a reflection of the fundamental alienness of computers, what they find quite easy you find quite hard and vice verca. Optimizing for huamans means generality and ruthless hiding of details, optimizing for machines is all about special cases and ruthless exploitation of assumptions. (Incidentally, C is not all what it's cracked up to be. Generic containers, off the top of my head, resort to using void* pointers for data and function pointers for operation, which has a runtime cost besides being unsafe and error-prone. Templates in C++ can aggressively inline types and operations for you, on the other hand as if you haven't written generic code at all, no wonder templates is the poster boy for C++'s 0-Cost abstractions. Another example I hear often is how pointer semantics in C and C++ makes it extraordinarily difficult for the compiler to optimize array and memory operations, whereas a language like Fortran make it easier by not having pointers.)
- Shorel 4y agoFor many things, I have found this easy language is C++. I use JavaScript and C++ for different things, sometimes in the same day. (And python and PHP and others, but this is not relevant.) Believe me, JavaScript can be a real head scratcher compared to C++. And now for the purists: No, I don't use all features of C++, only the minimal necessary ones for the problem I have to solve. This ridiculous idea that you are not using C++ if you are not using every single language feature is what makes programs difficult to write and maintain.
- corford 4y agoWe do. It's called D
- corford 4y agoOr VLang: https://news.ycombinator.com/item?id=31944777 https://news.ycombinator.com/item?id=31944777
- mikewarot 4y ago>Why can't we have a language easy to read and maintain but also have the speed of C? Swap out { } for Begin End, and make a few other changes, and you've got Pascal. Single pass pascal compilers have been faster (at compiling) that almost anything out there since Turbo Pascal 3.0 for MS-DOS. Modern versions, such as Free Pascal, Delphi and Lazarus also deal with strings in a manner that totally avoids needing to manually manage memory. The GUI builders are awesome as well.