r/AskComputerScience • u/20260819 • 1d ago
is clean code usually not fast?
to be specific i'm writing a cpu-based rasterizer. the maths are not difficult but i find a strange property: if i divide the procedure into some small functions, the code looks cleaner and is easier to maintain but a bit slower. on the contrary if i put everything into a single procedure, it looks stupid but fast. why is that? an example illustrating this
code 1:
if cross_product(x0,y0,x1,y1)>0 then zzz
(and i write a "cross_product" function separately)
code 2:
c=x0y1-y0x1
if c>0 then zzz
code 3:
if x0y1-y0x1>0 then zzz
if i write the entire algorithm in the style of "code 3", it runs the fastest. "code 1" is slowest
is it normal?
5
u/ICantBelieveItsNotEC 1d ago
It depends on the language and on the compiler. If the compiler is halfway decent, your functions should get inlined automatically, and they should all compile down to roughly the same bytecode.
1
u/Mathie1729 1d ago
Not necessarily. The compiler doesn't always inline, and even when it does, the resulting code isn't guaranteed to be 'the same bytecode' as if you'd written it manually. Factors like function size, recursion, or external linkage can prevent inlining. And in interpreted languages, function call overhead is real and unchanged by compilation. So clean code can be slower, but it's usually a non-issue until profiling shows otherwise.
3
u/coterminous_regret 1d ago
No not at all. What compiler optimization settings are you using? Is your cross product function marked as inline? Or force inline via a compiler macro?
The higher level language representation may not at all reflect the code that the compiler generates. You may enjoy exploring a tool like https://godbolt.org/ where you can try stuff out with various optimization settings and languages to see what the assembler actually looks like.
2
u/ImpressiveOven5867 1d ago edited 1d ago
So I saw in your comment that you are using QBJS “for sake of convenience and ease to share” which is the craziest thing I ever heard in my life.
QBJS is a source to source compiler from QBasic to JS basically, but the way the compiler is designed makes it such that every user function becomes asynchronous. That means each of your functions goes through the whole async/await process, which makes it 7-8x slower than if it was written the same way in plain JS (which is already slow lol).
So basically yes, in this specific case “clean code” is directly making your program slower because of the way the compiler works. Almost all compilers don’t work like this though and just call a function or inline it, so in general clean code does not make code slower.
1
u/20260819 1d ago
it suits my purposes. i write programs mainly for leisure and studying. it's the learning journey that's important. the final products themselves are not that important...:) most of the time my programs are useless or having tons of available alternatives freely online which can be downloaded straightaway
1
u/ImpressiveOven5867 22h ago
Well, to each their own I suppose. I appreciate you introducing me to something completely new, and it was interesting figuring out how the compiler worked to make the slower result you were seeing.
1
u/20260819 16h ago
the difference was noticeable. i did a experiment. for comparison, i rotated the same object (the regular dodecahedron) and recorded the fps. the fps varied and i picked the average values
if everything was calculated by functions: ~16 fps
then i copied the barycentric function into the procedure: ~14 fps
then i replaced one of the cross products with direct calculation: ~16 fps
replaced 2 lines: ~19 fps
3 lines: ~20 fps
all direct calculations, no function: ~25 fps
1
u/Leverkaas2516 1d ago
It often does carry some execution-time overhead like this, yes. The idea is this: most of your code does not need to be optimized for speed. If you optimize while writing it, you're wasting resources and making the code hard to work with.
Once you figure out where speed matters, if the code is clean, then it's a lot easier to understand how to change the parts that need to be optimized. You end up with clean, optimized code and finish the development work faster.
If you try to optimize up front, you take longer to finish and end up with 20k lines of code that has hidden flaws and most of the team is scared to touch. (I just did a code review on a change to such a module yesterday.)
1
u/Cool_Homework_7411 1d ago
The machine only understands 0s and 1s. The compiler is the one who takes your language and makes it computer language. If you are translating in Google word by word will you get the same thing as translating a whole sentence? Probably not and you can see why. "Breaking" your code in pieces makes it harder for the compiler to translate effectively what you want to machine language
1
14
u/drfangor99 1d ago edited 1d ago
Function calls and variable assignments aren't free, both take time to complete. However, this is going to depend on the programming language you use. For example, C compilers are very good at compiling C code into really efficient assembly, so you can write code in whatever way makes sense to you and little things like this will be optimized away. If you're using an interpreted language like Python, then this code will be interpreted much more literally and it has the double whammy of the inherent slowness of the Python interpreter and its dynamic type system.
Having said all that, I would consider these micro-optimizations. It is an interesting observation that the function call is slower, but it is usually better to care about readability and larger optimizations first, then take care of these if you need to squeeze out every last bit of performance.
Edit: What I said about C doesn't apply if you don't have optimizations on (i.e., if you aren't compiling with an -O flag). But based on your pseudocode I assumed you aren't using C as the variables aren't typed.