My takeaway is that unoptimized c++ is pretty close to the same performance as JavaScript. Wild.
fwiw https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
61–70 of 234 posts
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#62Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#63Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#64I like the OCaml version. It's both very easy to read and comes out really well in the benchmark. I also looked at the "simple" Zig version, which came out really well in the benchmark, and to me it didn't look simple at all. It seems you need to make a lot of low level details explicit. But IMHO AWK takes the crown here. :)
> But IMHO AWK takes the crown here. :) Agreed! AWK is still the king of this stuff. For tasks like this, I kinda think AWK is nigh-unbeatable: so simple to write, so obvious what's going on (even if you've never seen any AWK program before, you're probably going to be able to figure out what's going on there), and decently performant. AWK is the bee's knees.
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#65The programs are not comparable in the the following ways:
- Case: TFA requires (at least) ASCII lowercasing but the contest problem required no lowercasing.
- Ordering: TFA does not require sorting, but the contest problem required sorting.
- Memory: TFA imposes a requirement phrased as "don't read the whole file into memory" and this sounds like it's a resource-saving constraint, but it's usually a constraint that requires the program to spend additional resources. You could just mmap the file and store pointers into the mapped region. It costs extra to do copies instead of no copies.
- Text: TFA is unclear on what assumptions may be made about the lengths of words. For the contest problem, the Hungarian wikipedia input's longest word is around 80k.
- Safe, Hashing, Stdlib: TFA imposes some restrictions on what constructs may be used that are not imposed in the contest problem.
For the contest version of this problem, it seems like you can tokenize, hash, and count strings at around 1GB/s. Adapting a solution to solve TFA's problem (but not to conform to its Safe/Hashing/Stdlib requirements) would probably not carry too large of a penalty, since it's like 3 instructions to ASCII-lowercase 32 bytes and 1 string copy per unique string should take negligible time compared to the hash table lookups. So there is some room for the optimized solutions to go a little faster, if more optimizations are permitted.
[0]: https://easyperf.net/blog/2022/05/28/Performance-analysis-an...
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#66Earlier quoted context omitted.
The problem specified declares the words we're counting are ASCII: > ASCII: it’s okay to only support ASCII for the whitespace handling and lowercase operation UTF-8 (quite deliberately) is a superset of ASCII. So a UTF-8 solution is correct for ASCII, but a bytes-as-ASCII solution works fine in Rust if you only need ASCII. This is why Rust provides ASCII variants of a lot of functions on strings, and the same functi…
>> ASCII: it’s okay to only support ASCII for the whitespace handling and lowercase operation That's a somewhat specific list -- at least I didn't read that as a general "the program can assume that the input is only ASCII". But then, the author seems to have accepted solutions that crash on non-UTF8 sequences and ones that byte-compare them, so probably either behavior was meant to be fine. I just don't get that fro…
I don't think it assumes the input is only ASCII. If the problem is "given UTF-8 text, split on ASCII whitespace and convert ASCII uppercase letters to lowercase," you can do that correctly (and produce correct UTF-8 output) without really being UTF-8 aware. For why, see here: https://en.wikipedia.org/wiki/UTF-8#Encoding
> But then, the author seems to have accepted solutions that crash on non-UTF8 sequences and ones that byte-compare them, so probably either behavior was meant to be fine. I just don't get that from this rule.
That's a separate concern right? The rules are only about the behavior when the program is given UTF-8 input.
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#67Earlier quoted context omitted.
Can we move past the whole "it is not really python to use libraries written in C", especially when talking pure stdlib python? Python is basically a DSL for C extensions. That is the whole point. It would be like criticizing any compiled language for essentially being a DSL for machine code, and not "Real Instructions". Python's ability to interop with pre-built, optimized libraries with a lightweight interface is a…
I am not criticizing Python. It does well enough what it was made to do. It just make no sense to call that particular example a "language performance comparison". It is anything but.
* looking up a reference of an attribute with a string key underpins the meat and potatoes of python's execution model
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#68Earlier quoted context omitted.
Indeed. The original title is: > Performance comparison: counting words in Python, Go, C++, C, AWK, Forth, and Rust. Which means the submitter actively chose Go to be removed from the title. Judging from their post history they are aligned with Rust community.
The original title is 2 characters over the HN title length limit. I suspect they dropped "Go" first, because it's the language which has a 2-letter name, and they they editorialised it further to hint that there are more languages.
Removing any of them would suffice.
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#69I took the source code file size from the repository, and the runtime from the blog post.
Then I made an arbitrary overall "PAIN SCORE" (lower is better) by multiplying code size * runtime. I suggest this is a worthwhile metric simply because lower is better on both axes, but of course, in the "real world" there will be different economic costs to CPU time and developer time depending on the use case. Here's the sorted results, from least "pain" to most:
LANGUAGE FILENAME CODE SIZE RUNTIME PAIN SCORE (LOWER IS BETTER)
Shell optimized.sh 75 bytes 1.83 s 137.25
Crystal simple.cr 240 bytes 1.29 s 309.6
Nim simple.nim 424 bytes 0.77 s 326.48
Python simple.py 208 bytes 2.21 s 459.68
Ruby simple.rb 175 bytes 3.17 s 554.75
Go optimized.go 1514 bytes 0.40 s 605.6
Python optimized.py 464 bytes 1.33 s 617.12
Zig optimized.zig 2688 bytes 0.24 s 645.12
Go simple.go 688 bytes 1.12 s 770.56
Zig simple.zig 1394 bytes 0.55 s 766.7
Nim optimized.nim 1683 bytes 0.49 s 824.67
Shell simple.sh 60 bytes 14.81 s 888.6
Ruby optimized.rb 401 bytes 2.47 s 990.47
JavaScript simple.js 532 bytes 1.88 s 1000.16
C optimized.c 4360 bytes 0.23 s 1002.80
Rust optimized.rs 3065 bytes 0.43 s 1317.95
Swift simple.swift 317 bytes 4.23 s 1340.91
JavaScript optimized.js 1501 bytes 1.10 s 1651.1
C simple.c 2735 bytes 0.96 s 2625.6
Rust simple.rs 2239 bytes 1.38 s 3089.82
Sorting only by code size, the most concise implementations are: Shell, Ruby, Python, Crystal. Nobody was aiming to play code golf (i.e. minimize source code size), so these are fairly straightforward, idiomatic, readable implementations.I am definitely a Crystal fan, in fact this afternoon I'm continuing to implement suggestions from my recent Show HN https://news.ycombinator.com/item?id=32081943 comments. :)
Re: Performance comparison: counting words in Python, C/C++, Awk, Rust, and more
#70Earlier quoted context omitted.
The original title is 2 characters over the HN title length limit. I suspect they dropped "Go" first, because it's the language which has a 2-letter name, and they they editorialised it further to hint that there are more languages.
Leaving Awk over the vastly more popular Go, hints a more probable and frequent behaviour: bias. Removing any of them would suffice.