logoalt Hacker News

4 billion if statements (2023)

616 pointsby damethos12/06/2025171 commentsview on HN

Comments

xnorswapyesterday at 3:45 PM

This is time efficient* but rather wasteful of space.

The best way to save space is to use a Bloom Filter.

If we capture all the even numbers, that would sadly only give us "Definitely not Even" or "Maybe Even".

But for just the cost of doubling our space, we can use two Bloom filters!

So we can construct one bloom filter capturing even numbers, and another bloom filter capturing odd numbers.

Now we have "Definitely not Even" and "Maybe Even" but also "Definitely not Odd" and "Maybe Odd".

In this manner, we can use the "evens" filter to find the odd numbers and the "odds" filter to find the even numbers.

Having done this, we'll be left with just a handful of unlucky numbers that are recorded as both "Maybe even" and "Maybe odd". These will surely be few enough in number that we can special case these in our if/else block.

The filters as a first-pass will save gigabytes of memory!

show 3 replies
ZeroConcernsyesterday at 11:39 AM

Ah, yes, exactly the pointless diversion I needed for my lunch break. For science: generating a C# switch statement for similar purposes took 7 minutes on similar-ish hardware, but the resulting 99.2GB file could not be opened or compiled ('Stream is too long'), which was slightly disappointing.

Optimization efforts included increasing the internal buffer size of the StreamWriter used to create the source code: this reduced the runtime to around 6 minutes, as well as running a non-debug build, as it was observed that the poor Visual Studio metrics gathering process was contributing significantly to disk activity as well, but that ultimately didn't matter much. So, ehhm, yes, good job on that I guess?

show 4 replies
mft_yesterday at 1:04 PM

Similar humour if opposite directions to an old favourite: https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/

show 1 reply
kaygeyesterday at 4:26 PM

> any value over 2^31 seems to give random results.

Wow he really lucked out... On his way to perfecting a fully functioning and performant Even/Odd Detector, he stumbled upon a fully functioning and performant Coin Flip Simulator!

thedougdyesterday at 4:11 PM

I took an ASIC design class in college, unfortunately with a heavy course load that didn't allow me to focus on it. For our final project we were given a numbered dictionary and asked to design a chip that would accept the characters on a 7 bit interface (ASCII), one character per clock cycle and output the dictionary number on an output interface but I can't remember how wide. We were graded on the size of the resulting ASIC and how many clock cycles it took from the last character in to the number on the output.

I started designing my modules, a ROM, a register with a ROM pointer, etc, etc, writing the Verilog and working out the clock sync between modules. Then I got 'lazy' and wrote a trie tree like implementation in Java, and have it spit out the whole tree in Verilog. It worked and just one clock cycle after the last letter my number would output. Fastest in the class! Also the most number of gates in the class. Surprised I got a 90 grade given I didn't use any of the advanced ASIC design the class taught. The TA didn't know what the hell they were looking at.

show 1 reply
wiz21cyesterday at 11:22 AM

Gemini took 4 seconds to answer this prompt: "Here is a number 4200020010101. Think deeply about it and tell me if it is not or or not even."

So if you're concerned with privacy issues, you can run the assembly version proposed in the article locally and be well within the same order of performance.

Let's thank the author of the article for providing a decent alternative to Google.

ah, but the license is not that good we can't reproduce his code.

show 3 replies
blauditoreyesterday at 2:04 PM

This could be obviously done with much less code: Just add "if"s for all even number, and at the end just return "odd" if none of the evens matched. 50% less code!

Or even simpler: If it's 0, return "even". If not, do a recursive call to n-1, if that equals "even", return "odd", otherwise return "even".

But the best way is probably to just use a library. Yes, 500MB of additional dependencies, but then it's a one-liner.

show 2 replies
xg15yesterday at 11:30 AM

> Now, this is a time-memory tradeoff, but my time on this earth is limited so I decided to meta-program the if statements using a programmer program in a different programming language.

  for i in range(2*8):
    if i % 2 == 0:
No comment...
show 5 replies
_kst_yesterday at 9:07 PM

The author missed an opportunity for a much shorter solution for the given problem statement.

    // Check whether a number is odd or even.

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>

    static bool is_odd_or_even(unsigned long num) {
        return true;
    }

    int main(int argc, char **argv) {
        const unsigned long num = strtoul(argv[1], NULL, 10);
        printf("%lu is %s odd or even\n",
               num,
               is_odd_or_even(num) ? "is" : "is not");
    }
show 1 reply
mring33621yesterday at 2:48 PM

I recently asked a Qwen model to write me some code to remove errant spaces ("c he es e" instead of "cheese") in OCR'd text. It proceeded to write 'if' blocks for every combo of all English words and all possible errant spaces. I did not wait for it to finish...

orzigyesterday at 11:28 AM

If the author is available for consulting I have this bag of rice I need cooked. Should be around 30,000 grains, each needs about 1mL of water and 2m on the stove. Will pay $10 (2025 dollars)

show 1 reply
billforsternzyesterday at 10:19 PM

I know it's silly, but I just want to fix his first version with the minimum possible changes;

  /* Copyright 2023. All unauthorized distribution of this source code
     will be persecuted to the fullest extent of the law*/
  #include <stdio.h>
  #include <stdint.h>
  #include <string.h>
  int main(int argc, char* argv[])
  {
      uint8_t number = argc>1 ? argv[1][strlen(argv[1])-1]-'0' : printf("Usage: odd-or-even number\n");
      if (number == 0)
          printf("even\n");
      if (number == 1)
          printf("odd\n");
      if (number == 2)
          printf("even\n");
      if (number == 3)
          printf("odd\n");
      if (number == 4)
          printf("even\n");
      if (number == 5)
          printf("odd\n");
      if (number == 6)
          printf("even\n");
      if (number == 7)
          printf("odd\n");
      if (number == 8)
          printf("even\n");
      if (number == 9)
          printf("odd\n");
      if (number == 10)
          printf("even\n");
  }
This way it basically works. It's a shame that it doesn't call out a non numeric argument but that's about the only problem. It relies on a trick, printf() returns the number of characters printed, so the error message string needs to be longer than 10.
show 1 reply
travisgriggsyesterday at 3:24 PM

I see this is 2023… the article refs GPT even then. Can’t believe it’s already that much time gone by, still seems like “last years big news”

I was gonna comment “this is what I really like to see on HN”. Then I saw the date and was sad that we’re having to dip into the history box to find fun/interesting articles more often of late it seems.

Anyone else interested in a temporary moratorium on all things LLM? We could have GPT-free-Wednesday, or something like that :)

show 3 replies
oneeyedpigeonyesterday at 12:10 PM

I prefer data-driven programming, so a simple:

    return odd_or_evenness[n];
works for me, alongside a pretty big array.
show 4 replies
jagged-chiselyesterday at 12:09 PM

I have never seen anyone argue for a ‘switch’ version.

    switch (v) {
     case: 0,2,4,8,…:
       return EVEN;
     case: 1,3,5,7,…:
       return ODD;
     default:
       return IDK;
    }
Slightly less code to generate.
show 1 reply
fainpulyesterday at 6:20 PM

Any good engineer knows there is no "best" solution, only tradeoffs.

Save space.

  def even_flip_flop(number):
    even = True
    for _ in range(number):
      even = not even
    return even

Ditto. Sure, this overflows the stack, but you look cool doing it.

  def even_recursive(number):
    return True if number == 0 else not even_recursive(number - 1)

Save time. Just buy more RAM.

  table = [True, False] * 1000  # adjust to your needs
  def even_lookup(number):
    return table[number]
show 1 reply
thewisenerdyesterday at 10:33 AM

discussed 2 years ago,

https://news.ycombinator.com/item?id=38790597

4B If Statements (469 comments)

show 1 reply
isoprophlexyesterday at 10:57 AM

> Visionary genius Ross van der Gussom

Thanks for making me doubt myself & googling who that guy who made python was again, because surely "van der Gussom" isn't a normal Dutch name. Well played.

show 1 reply
SiempreViernesyesterday at 10:36 AM

> As a side note, the program is amazingly performant. For small numbers the results are instantaneous and for the large number close to the 2^32 limit the result is still returned in around 10 seconds.

Amazing!

show 1 reply
lubujacksonyesterday at 4:43 PM

God help us if that code ever makes it's way onto npm.

isEven is a performant, hand-compiled evenness checker for any 32 bit integer. A single file import that does one job and one job only!

show 1 reply
rossdavidhyesterday at 5:33 PM

Really if you are not making custom silicon for this problem, you are just wasting our time here aren't you.

show 1 reply
Ensorceledyesterday at 9:07 PM

I just had flash backs to a previous job where I was brought in to optimize another teams builds since they were now taking minutes instead of seconds.

I tracked it down to a folder with thousands of C++ files called things like uint_to_int.cc and inch_to_cm.cc and cm_to_m.cc. Basically the developer in charge of writing the conversion library took our typed units library and autogenerated a C++ file for every possible conversion the application might need to make.

Every time we added a new typed unit it would create another couple of dozen files to be compiled.

avandecremeyesterday at 7:22 PM

This reminds me of when I learned to program on my casio calculator.

There was a function to detect a key press which would return a number identifying the pressed key.

I needed to map that number to the letter printed on the key to print it on the screen. I don't remember whether there was no hashmap data structure or I just didn't know about it, but I implemented it with a serie of if.

The problem with that solution is that while mapping A was fast, Z was very slow because it was at the end of the list. That is how I discovered divide and conquer/ dichotomy with if branches.

dorianmariecomyesterday at 8:04 PM

i tried in ruby up to 1 million (1 billion was taking too long)

    File.write("check.rb", (["if i == 0\n  puts :even"] + (1..1_000_000).map { |i| "elsif i == #{i}\n  puts :#{i % 2 == 0 ? "even" : "odd"}" } + ["end\n"]).join("\n"))
and added at the top

    i = ARGV.first.to_i
but i'm getting SIGILL

    fish: Job 1, 'ruby check.rb 0' terminated by signal SIGILL (Illegal instruction)
show 1 reply
rplntyesterday at 10:47 PM

Can't you just implement javascript interpreter and import is-even package like normal developers?

KeplerBoyyesterday at 11:50 AM

kind of expected gcc to see right through the 300 gigs of code and compile it down to the tenish instructions.

show 3 replies
whynotmaybeyesterday at 11:47 AM

> I decided to implement this in the C programming language as it’s by far the fastest language on the planet to this day (thanks to the visionary genius Dennis Richie)

Am I lost? Aren't the compiler/linker responsible for fast code, not the language itself?

show 5 replies
philipptayesterday at 11:56 AM

> I saw from the SSD was around 800 MB/s (which doesn’t really make sense as that should give execution speeds at 40+ seconds, but computers are magical so who knows what is going on).

If anyone knows what’s actually going on, please do tell.

show 2 replies
zkmonyesterday at 6:51 PM

Infact, some really performant code such as glMatrix.js do not use any for loops for matrix math, just to allow the javascript engine to optimize the code as much as possible.

https://github.com/toji/gl-matrix/blob/master/dist/gl-matrix...

SatvikBeriyesterday at 5:33 PM

> How did I do this? Well I jumped online, using a mix of my early life experience coding emulators and hacking and looked into the x86(-64) architecture manuals to figure out the correct opcodes and format for each instruction. … Just kidding, that’s horrible. I asked ChatGPT

Ok but if you do want to play with writing binary code manually I recommend Casey Muratori's performance course

mgaunardyesterday at 1:27 PM

A much cooler approach would have been to generate the ASM from the same program, rather than generate a file from python and load that file from C++. The multi-stage build and filesystem are completely unnecessary.

The technique actually has a lot of practical applications, so it's useful to have a C++ library that helps you with generating amd64 machine code.

1a527dd5yesterday at 12:48 PM

I love "stupid" stuff like this; you normally learn something small and seemingly inane. It's fun!

runtimepanicyesterday at 4:41 PM

The interesting part isn’t the if-statement count but how quickly the compiler and branch predictor erase the differences. It’s a nice demo of why “manual cleverness” rarely beats modern toolchains.

quuxyesterday at 9:02 PM

I kept waiting for the payoff to be "The optimizer reduced the entire series of if statements to a single instruction"

Sulf1retoday at 12:18 AM

I don't get it. why not just look look at the last binary bit?

show 1 reply
riwskyyesterday at 2:58 PM

Would be more maintainable if they injected the loading strategy to be used as a dependency from config instead of hardcoding it :/

almosthereyesterday at 6:50 PM

If you were to convert an llm model into code, it would have like 500 billion if statements like that

layer8yesterday at 2:08 PM

This is also a nice approach for FizzBuzz in leetcode interviews.

Moreover, interviewers will be smitten by the hand-optimized assembly code.

tomaskafkayesterday at 1:40 PM

Oh, I have an idea for better leftpad implementation, let me publish that to npm real quick!

tigranbsyesterday at 11:19 AM

This reminds me of my personal "prime number" grabber research https://github.com/tigranbs/prime-numbers I needed to create the unique graph nodes and assign prime numbers, and to make things efficient, I thought, why not just download the list of known prime numbers instead of generating them one by one. So I did and compiled everything with a single Go binary. Ehh, good old days with a nice feith in making "the best" crappy software out there.

taylorallredyesterday at 6:26 PM

Meanwhile:

    not     eax
    and     eax, 1
nonethewiseryesterday at 3:48 PM

Configuration over logic. At a new scale enabled by AI.

asgsyesterday at 10:23 PM

no but thank you. i will stick to using npm's is-odd and is-even packages

wvbdmpyesterday at 11:32 AM

Next put them in a tree for faster lookups.

show 2 replies
shevy-javayesterday at 1:03 PM

Damn it - my code got leaked!

pcthrowawayyesterday at 11:35 PM

> As a side note, the program is amazingly performant. For small numbers the results are instantaneous and for the large number close to the 2^32 limit the result is still returned in around 10 seconds.

Lol

Exumayesterday at 5:05 PM

This is good stuff

ks2048yesterday at 2:06 PM

Silly. Don't waste your time on problems other people have already solved! Use JS and "npm install odd_or_even".

🔗 View 6 more comments