Following on the recent “faster than wc” blogposts, I decided to end this fad once and for all, using the best language ever created : Brainfuck.
>>,+><[-----------[----------------------[>+<<-[<+>+]>[-]][-]]<[-]>>[<<+>>-]<,+]<[-]<[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]>++++++++++.
Well, obviously, that’s not very readable. We just needed to put that in for the sweet clickbait ;)
Here is the actual code :
VARIABLES (in cell order) :
total = 0
> was_letter = 0
> input ,+
> tmp0
while the input isn't EOF : we count words <[-
---------- if input is not a newline [
---------------------- if input is not a space [
>+ tmp0 = 1
<<-[<+>+]> if not was_letter increment total
[-]]
[-]]
<[-] clear was_letter
>>[<<+>>-] move tmp0 to was_letter
<, take input again
+]
<[-]<
print the total (nothing new)
[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>]<<<<<]>[-]++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]
>++++++++++.
To get the maximum performance out of it, I choose to use funkicrab, which totally doesn’t compile to C (I used clang with -O3
, if you are wondering). Since cells need to be 32-bit for counting more than 255 words, you’ll also need to replace the few occurrences of char
to int
.
So, how fast can it run ?
$ cat words.txt | time wc -w
13018291
0.52 user
0.01 system
0:00.55 elapsed
$ cat words.txt | time ./bfwc
13018291
0.50 user
0.02 system
0:00.54 elapsed
Looks like we won a hundredth of a second counting the number of words in a 85 Megabyte file. Which I do all day, every day, so I’m now relaxing by thinking about all the free time I gained.
Wait, of course not, this was a complete waste of time. Hope you enjoyed it nonetheless :)