Skip to content
DevMeme
3207 of 7435
Python's Unflattering Performance Review
Languages Post #3528, on Aug 12, 2021 in TG

Python's Unflattering Performance Review

Why is this Languages meme funny?

Level 1: The Tortoise and the Hare

Imagine a race between two characters: a friendly tortoise and a speedy hare. In our story, Python is like the tortoise and C is like the hare. Python (the tortoise) is very friendly and easy to work with – it takes its time, moves steadily, and makes sure every step is nice and clear. C (the hare) is super fast and powerful, zooming ahead at top speed, but to be that fast it’s a bit more wild and not as easy to handle if you’re not trained. Now, in the classic fable The Tortoise and the Hare, the tortoise wins in the end through patience and consistency. But in the programming world, when it comes to pure speed, the hare (C) usually wins the race every time if both are running under the same conditions. 🐢🏁🐇

This meme is funny because it’s like we’re watching Python brag about its good qualities – it’s saying “I’m known for being easy to understand, and I’m great for big data and science tasks!” with a big proud smile. These are true; Python is like that helpful friend who explains things in a simple way and has all the tools you need ready to go. Then, the other character (like the boss in the scene, or think of it as the hare poking fun) says, “...and you’re also known for being slower than C.” It’s as if the hare leans over and teases, “you may be nice, but you sure take your sweet time!” At this point, Python’s smile fades and it looks a bit embarrassed or upset, just like anyone would if their weakness was pointed out after their strengths.

In very simple terms, the meme is telling a joke about not being able to have everything perfect. Python the friendly tortoise can’t also be the fastest runner — those two things (being super easy and super fast) are kind of opposites in many cases. It’s like if you have a very easy, step-by-step way of doing something, it might not get done as quickly as a more direct but complicated way. People find it funny because they imagine Python as a person hearing compliments and then a gentle criticism, and Python making that “ouch, you got me there” face. If you’ve ever been really good at something but had a little flaw that your friends tease you about, you know the feeling! For programmers, we kind of treat our favorite languages like buddies, and Python is that buddy who everyone likes but we chuckle about how it’s not the speediest. The meme captures that feeling in a simple, relatable way: you can be lovable and capable (Python), yet still have that one thing (speed) that you’re just not the best at, and that’s okay. That contrast is the whole joke – and why it makes developers grin and think, “So true, poor Python!”

Level 2: Readable but Not Rapid

Let’s break down the joke in simpler terms. Python is a programming language known for being very readable and easy to use. When people say Python is "easy to understand," they mean the code syntax is designed to be clean and kind of intuitive. For example, in Python if you want to print a message, you just do:

print("Hello, World!")

In C, doing the same thing takes a bit more work and looks more complex:

#include <stdio.h>   // include a library for input/output

int main() {
    printf("Hello, World!\n");  // print the message
    return 0;                   // end the program
}

The Python version is one straightforward line, essentially telling the computer “print this message.” It reads almost like English. The C version has a lot more ceremony around it – you have to include a library, define a main function, use a specific function printf, and end the program explicitly. This little example shows why Python is celebrated for being easy to understand and write. You spend less time on setup and syntax and more time on the actual problem you're solving. Python enforces indentation to structure code instead of lots of { } braces or keywords, which many find makes the code visually cleaner. All these language quirks (like using whitespace and having high-level constructs built-in) make Python code often look quite straightforward, even to a relatively new programmer.

Now, Python is not just popular for toy examples — it shines in real-world fields like data science and scientific computing. When the meme says Python is known for its "libraries in data science," think of libraries as pre-built packages or toolkits. Python has an extensive collection of these packages that are widely used in data analysis, machine learning, and artificial intelligence. For instance:

  • Pandas: A library that makes it easy to load, manipulate, and analyze data tables (like Excel sheets or SQL tables) in just a few lines.
  • NumPy: Provides powerful tools for working with arrays and matrices of numbers – essential for math, stats, and science tasks.
  • Matplotlib and Seaborn: For creating graphs and charts from data.
  • SciKit-Learn: For machine learning algorithms (like training models to make predictions).
  • TensorFlow and PyTorch: For building and training neural networks (used in deep learning).

Because of these libraries, someone working with data can do a lot of complex stuff quickly in Python. Say you want to analyze a million-row dataset and plot some trends; with Python’s libraries, you can accomplish that with just a few commands, whereas doing it from scratch in a language like C would be a huge project (you’d have to handle file I/O, math, plotting logic, etc., mostly on your own or with less integrated libraries). That’s why Python is often joked about as the “Swiss Army knife” of data science – not necessarily because it’s the fastest at doing calculations, but because it gives you all the tools in an easy-to-use way. It’s very productive for the person writing the code.

However, this convenience and ease come with a well-known downside: Python is generally slower in execution speed compared to a language like C. When the meme says Python is known for "being slower than C," it refers to the fact that programs written in Python typically run with more delay or use more CPU time to do the same task than if that program were written in C. If you had a race, Python would be the slower contestant and C the faster one.

Why is Python slower? One big reason is how they run programs. C is a compiled language. "Compiled" means you write your code, then a special tool (a compiler) translates that human-readable C code into machine code (the very detailed instructions that the computer’s hardware understands). Once compiled, the program runs directly on the machine. Python is an interpreted language. "Interpreted" means you don’t compile the code down to raw machine instructions ahead of time. Instead, another program (the Python interpreter) reads your Python code and executes it on the fly, line by line, figuring out what each instruction means as it goes. This interpretation process acts like an extra layer: it makes coding easier (because you can run code immediately and it’s very flexible), but it also means each operation has a bit more work to do. It’s like the difference between reading a book in your native language (C’s way) versus reading a book with the help of a translator translating every sentence live (Python’s way). The translated one is going to take longer to get through, right?

Another reason is Python’s dynamic typing. In Python, you don’t have to declare the type of each variable; the language figures it out at runtime. For example, you can just do x = 5 without specifying if x is an integer, a float, etc., and later even do x = "hello" assigning a string to the same variable. That’s very convenient, but behind the scenes, Python has to keep extra information about what type x is, and every time you use x in an operation, it has to check that info. In C, if you declare int x = 5;, the compiler knows x is an integer and it stays an integer (no changing types). So operations on x in C are straightforward and directly use the fact that it’s an integer. In Python, this flexibility adds overhead — it’s like each time Python does something, it carries a backpack of context (type info, safety checks) that slows it down a bit, whereas C travels light but you had to pack carefully upfront.

In practice, this means if you write a program to do something heavy, like crunch through millions of calculations or process a huge file, a pure Python version might run significantly slower than a C version of the same algorithm. We’re talking differences that can be 10 times slower, 50 times slower, sometimes even more, depending on the task. For example, a loop doing a simple arithmetic operation a million times could be done in a blink in C, but might take noticeable time in Python. That’s why Python developers often rely on those optimized libraries: those libraries internally use C/C++ or optimized code for the heavy parts, so you get the ease of Python without paying the full performance price. It’s a bit ironic — Python is slower, but it stays super useful by quietly borrowing speed from C in exactly the scenarios where raw speed really matters (like heavy math).

So the meme is funny to developers because it lists Python’s great qualities – readability (easy for humans to read) and usefulness in data science (tons of tools ready to go) – and then adds, “but hey, isn’t it also known for being slow?” It’s pointing out a kind of well-known irony or language quirk: you get all these nice things with Python, and in exchange, you accept that it won’t win a race against a lower-level language like C. Pretty much every programming language has something it’s good at and some trade-off or downside. In Python’s case: human-friendly, yes; lightning-fast execution, not so much.

For a junior developer or someone just learning, this meme also conveys a gentle lesson: When picking a language or a tool, remember there’s no free lunch. If something is super beginner-friendly and powerful (like Python is for writing code and doing complex tasks easily), it might have hidden costs such as performance. Conversely, languages known for being extremely fast and powerful (like C, or C++ or Rust) often have a steep learning curve or require you to manage a lot more details manually. It’s why Python and C often get compared – they kind of sit at opposite ends of the spectrum in many ways.

The context of the meme using The Office setup emphasizes the humor: imagine Python as a proud employee listing their strengths in a performance review – “I write very clear code, I’ve become the star of data science projects” – and then the boss reminds them of the area they got a low score in: “speed (performance)”. Python’s face falls, because, well, it’s true and there’s no denying it. 😅 Developers find this funny because we personify programming languages like this all the time, almost like they have personalities. Python’s personality in this meme is the super helpful, nice co-worker who unfortunately is a bit slow getting the work done. C’s personality by contrast might be the efficient, no-nonsense worker who isn’t very approachable. Depending on the situation, you might prefer one or the other – and often in big projects, you actually use them together to balance things out.

In day-to-day terms, if you’re a newcomer: don’t worry that “Python is slower than C” means Python is bad. Not at all! It’s just a different tool. Think of it like a comfy family car vs a race car. A family sedan (Python) is comfortable, easy to drive, and has great features (like a good stereo, AC, lots of cupholders for your data science “beverages” 🍹), but it’s not the fastest car on the track. A Formula 1 race car (C) is extremely fast and powerful, but hard to drive and not very comfortable for everyday use. In coding, you pick the vehicle that makes sense: if you’re doing something where turning around code quickly and having simplicity matters (like trying out a data analysis or automating a small task), Python’s your friendly sedan. If you’re doing something where every millisecond counts (like a high-performance game engine or a program that runs on a tiny device with limited hardware), you might need the race car performance of C, and you’ll accept that it’s harder to handle. And sometimes, you use Python as the “driver” that directs some race car engines under the hood – which is exactly what those Python libraries do with C code. This meme basically gets a laugh by reminding us of Python’s “family car” nature in a cheeky way.

Level 3: The Price of Productivity

From a senior developer’s perspective, this meme highlights the classic performance trade-off we deal with when choosing a programming language. Python is often praised for its developer productivity and readability – writing Python tends to feel like writing in pseudocode or plain English. There's minimal ceremony: no worrying about types for every variable declaration, no intricate memory management, and a very clean, whitespace-significant syntax that many find easy to understand. This is why Python is frequently recommended as a first language to learn and why it has a reputation for being beginner-friendly. A seasoned engineer sees that caption "easy to understand" and nods: indeed, Python’s syntax (using indentation instead of curly braces, high-level constructs like list comprehensions, and a huge standard library of conveniences) lowers the barrier to entry for new developers and speeds up development for experienced ones. Many of us have experienced the joy of converting what would have been 50 lines of C or Java into 5 lines of Python that read almost like plain English. This is Python’s superpower: it optimizes developer time.

The second thing "Python" proudly points out in the meme is its powerhouse status in data science (captioned “libraries in data science” or "usefulness in data science"). Over the past decade or so, Python has become the go-to language for data analysis, machine learning, and scientific computing. This is largely thanks to an ecosystem of libraries (like NumPy, pandas, SciPy, scikit-learn, Matplotlib, TensorFlow, and PyTorch, to name a few) that let you do everything from crunch enormous datasets to train neural networks – often with just a few lines of high-level Python code. A seasoned dev knows that one reason Python won out in data science is not because it’s the absolute fastest at runtime, but because it’s fast to develop with, and you can lean on those libraries (many of which, as mentioned, are written in faster low-level languages internally) to handle the heavy lifting. The meme is spot-on with this contrast: Python is known for scientific and analytic computing today in a way that, say, C isn’t, despite C’s speed. Why? Because in practice, data scientists value being able to prototype and iterate quickly in Python, using those well-tested libraries, more than they value hand-optimizing every last bit of performance themselves. In industry, you’ll often hear a maxim like, “Hardware is cheap, but developer time is expensive.” Python embodies that ethos — it might use more CPU seconds, but it can save human hours, and that trade-off is usually worth it for many applications.

Now, the final punchline of the meme: “being slower than C.” Here the “manager” in the meme (Michael Scott from The Office, using the you_are_known_for format) delivers the well-known downside of Python right after the two big praises. This format is a setup for contrast: it’s funny because it’s true and a little bit embarrassing for Python. No matter how beloved Python is for its elegance and its data science dominance, every experienced developer knows that performance is Python’s Achilles’ heel. When it comes to raw execution speed, especially on CPU-bound tasks (like heavy computations, tight loops, or system-level tasks), Python just can’t keep up with a low-level language like C. The meme captures Python’s resigned face — that look of “yeah, I’ve heard this one before.” 🙃 It’s a shared joke among programmers: we adore Python for making our lives easier, but someone will always point out, often half-jokingly, “Ugh, Python is so slow compared to C!”

In real development scenarios, this trade-off leads to a lot of familiar patterns. Senior devs have seen projects initially built quickly in Python (because it was easy to get started) later hit performance bottlenecks. There’s almost a rite-of-passage story: a small script written in Python grows and becomes mission-critical, then one day it’s too slow for some task, and the team has to consider optimizing. That might mean refactoring the Python code, applying algorithms to do less work, or in some cases rewriting a hot module in C/C++ for speed. This is so common that it’s become an accepted approach: prototype in Python, optimize the critical parts in a faster language if needed. We jokingly call it the two-language solution – Python for productivity, C (or C++/Rust) for performance-sensitive innards. A seasoned engineer reading “slower than C” might recall the countless times they’ve had to explain to product managers why scaling a Python service might require more servers than a C++ service, or why that data processing job takes hours in pure Python but could run in minutes with a C extension (or simply by using vectorized NumPy calls). The humor in the meme is that it encapsulates this whole saga in one facial expression from The Office – Python enthusiastically touting its strengths, then being unable to dodge its well-known weakness.

We also recognize in this meme an affectionate ribbing of Python. In the developer community, poking fun at languages is part of the culture (you’ll see LanguageComparison jokes all the time). Python’s case is interesting because it’s almost universally liked for what it offers, even by people who criticize its speed. So the meme isn’t hating on Python; it’s more like that gentle joke you make about a friend’s little flaw. We laugh because we’ve all been there: maybe you wrote a quick script in Python that worked beautifully, but when you tried to use it on a huge dataset or under heavy load, you went “oh… this is kind of slow.” It’s relatable humor. And importantly, the meme resonates because if you’ve been in development long enough, you’ve learned that you can’t have everything in one language. Python chooses simplicity and power in expressiveness, C chooses control and speed. Each has its language quirks and domains where it shines. As a senior dev, you appreciate that trade-off: you use Python when you want to get results quickly and your bottleneck isn’t a tight inner loop (or you can push that loop to C via a library), and you use C (or similar system languages) when you absolutely need that raw performance or fine-grained control over memory and processor instructions.

The scene used in the meme (from The Office) adds another layer for those familiar: Michael Scott lists positive qualities of an employee (making them smile) and then throws in a negative one, which wipes the smile away. It’s a popular format for memes (“You are known for… good thing, ... another good thing, ... bad thing”). For developers, Python’s “bad thing” is practically a running gag. We’ve all seen benchmarks or heard colleagues jibe, “Sure, Python is great, but it’s not winning any speed contests.” The meme succinctly delivers that jibe. And the reason it’s funny and not offensive is because Python’s slowness is a well-acknowledged reality — even the most die-hard Pythonistas will shrug and go “yeah, fair point, it’s not as fast as C.” In fact, Python’s creator, Guido van Rossum, and the core development team have historically been quite open that Python prioritizes clear syntax and ease of use over raw speed. There’s a famous quote, “Python is fast enough for most things.” The community often cares more about whether the language is fast to write in (developer efficiency) and fast when using the right tools (like those optimized libraries) than about beating C in a micro-benchmark. So the meme lands as a light-hearted truth: Python wears its crown of popularity with pride, but that crown comes with an asterisk about performance. Seasoned devs have a fond chuckle because it captures the exact moment Python’s pride gets a reality check – a dynamic many of us have experienced firsthand in tech discussions and developer humor sessions.

In summary, the senior perspective here is recognizing the trade-offs in language design. Python’s strength is making coding easier and faster for humans, which has led to huge successes (like the explosion of data science and quick scripting). The cost of that choice is that the computer has to work harder (making Python code run slower at the machine level compared to lean, compiled C code). The meme humorously reminds us of this well-known cost. It’s “funny because it’s true,” and because it’s a shared piece of industry wisdom that no amount of Python love or hype can fully escape. Even in 2021 (when this meme was posted), after years of improvements and even projects trying to make Python faster, the core reality remains: Python trades speed of execution for speed of development, whereas C often does the opposite. And as developers, we’ve learned to choose between them (or combine them) wisely depending on what matters for the task at hand. The meme just packages that whole encyclopedic insight into a punchy visual joke.

Level 4: Beneath the Bytecode

At the lowest level, the contrast between Python and C comes down to how the computer actually runs their code. Python executes programs using an interpreter and bytecode, whereas C is executed as direct machine code after compilation. In Python's case (specifically the common CPython implementation), your .py source is first compiled into an intermediate bytecode (those .pyc files). That bytecode isn't the native language of the CPU — instead, a virtual machine (essentially a loop written in C) reads and performs each instruction. This indirection introduces overhead at runtime: every Python operation (even a simple x + y) must go through additional steps like type checking and dispatching to the appropriate C code under the hood. In contrast, C code is compiled all the way down to the CPU's own instructions ahead of time. When you run a C program, the processor is executing exactly the low-level operations you wrote (optimized by the compiler), with no middleman.

For example, consider adding up numbers in a list. In Python, each loop iteration and addition involves multiple layers of work (interpreting bytecode, managing Python objects, etc.), whereas in C it becomes a tight sequence of machine-level instructions:

# Python code (interpreted, dynamic):
total = 0
for x in numbers:
    total += x  # Each step involves interpreter overhead and dynamic type handling
// C code (compiled, static types):
int total = 0;
for (int i = 0; i < N; ++i) {
    total += numbers[i];  // Compiled into a few CPU instructions working directly with memory
}

In the C version, the compiled machine code might use a CPU register for total and loop with minimal instructions (add operations, pointer increments, a compare/jump for the loop). The Python version, by contrast, will internally call out to C functions (to perform the addition on Python objects) every iteration, manage reference counts for memory, and check types at runtime. This is why pure Python tends to be orders of magnitude slower for heavy computational loops. The computer has to do a lot more bookkeeping to execute the same abstract logic.

There are also deeper architectural reasons behind Python's speed limitations. Python uses high-level abstractions (like objects for everything, even simple integers) and a lot of indirection. Each integer 42 in Python isn’t just a raw 32-bit value like in C – it’s an object on the heap with metadata (type information, reference count, etc.). So adding two numbers in Python involves pointer dereferences and function calls (to handle arbitrarily large integers and various types), whereas in C it’s a single CPU ADD instruction on two registers. The cost of abstraction shows up in CPU caching and branch prediction too: C’s tight loops take advantage of contiguous memory and predictable instruction flow, keeping the processor’s pipeline and caches fed efficiently. Python’s interpreter, by contrast, is jumping around a general-purpose evaluation loop, which can be less friendly to the instruction pipeline and cause more cache misses due to its data being scattered (e.g., pointers to objects all over memory).

Another advanced factor is Python’s approach to multi-threading with the Global Interpreter Lock (GIL) in CPython. The GIL ensures only one thread executes Python bytecode at a time per process, which means even on a multi-core machine, Python won’t effortlessly speed up CPU-bound code by using threads. In C (or C++), you can spawn threads that truly run in parallel on different cores (provided you handle synchronization yourself). In Python, threads are useful for I/O-bound concurrency, but they don’t achieve parallel computation for CPU-bound tasks due to the GIL. This is another reason people say Python is “slow” for certain use cases – throwing more hardware at a Python program (more CPU cores) doesn’t help as much as it would in a C program, unless you use multi-processing or native extensions.

It’s worth noting that Python’s performance issues are well-understood, and the language has evolved strategies to mitigate them without sacrificing ease of use. Many of Python’s vaunted data science libraries (like NumPy, pandas, or TensorFlow) are actually written in C, C++, or even Fortran under the hood. Python acts as a friendly glue, an easy-to-use interface that orchestrates high-performance code behind the scenes. So when you do heavy number crunching in Python with NumPy, what’s happening is that you’re calling into highly optimized C/C++ routines (for example, vectorized operations that use SIMD instructions and efficient memory access). This way, Python can have its cake and eat it too: you write in a readable high-level syntax, but you’re leveraging the speed of low-level languages where it counts. The flip side is if you try to implement those heavy computations purely in Python (without native extensions), you’ll quickly run into that slowness the meme pokes fun at. There’s a well-known mantra among performance-minded Python developers: “If your Python is too slow, just do it in C (or let someone else’s library do it in C) under the hood.”

In academic terms, this is a classic example of the abstraction-performance trade-off. Python is a high-level language with lots of abstraction: automatic memory management (garbage collection via reference counting), dynamic typing, and a virtual machine layer. C is a low-level language (closer to the metal) where you manually manage memory (malloc/free), use static types, and compile straight to optimized machine code. Python sacrifices some raw performance to provide a high developer experience – quick coding, easy syntax, and an extensive runtime that handles details for you. C sacrifices ease (manual memory management, verbose syntax, higher chance of crashing on a bad pointer) to squeeze out maximum performance from the hardware. These design decisions are why the meme’s punchline (“being slower than C”) is fundamentally true: it’s practically baked into the physics and math of how the two languages work. Barring special techniques like JIT compilation (which some alternative Python implementations and other languages use to narrow the gap), an interpreted dynamic language will almost always run slower on the CPU than an optimized static compiled language for the equivalent task. It’s not just an unfortunate quirk – it’s the inevitable outcome of Python’s very philosophy of being high-level and flexible. And that is exactly why seasoned developers smirk at this meme: it humorously distills a well-known engineering trade-off into a simple Office scene.

Description

A six-panel meme using the 'You are known for...' format from the TV show 'The Office.' In the left panels, Michael Scott is conducting an interview. In the right panels, Pam Beesly is labeled 'Python.' In the first row, Michael begins, 'You are known for...' and Pam (as Python) excitedly answers, 'easy to understand'. Michael looks unconvinced. In the second row, Pam tries again with a confident smile, 'usefulness in data science'. In the final row, Michael delivers the punchline with a critical expression: 'being slower than c'. Pam's face shifts to one of utter disappointment. The meme humorously highlights the core trade-off of Python: its high-level syntax and powerful libraries make it excellent for developer productivity and data science, but as an interpreted language, its raw performance is a well-known weak spot compared to compiled languages like C

Comments

228
Anonymous ★ Top Pick Python: spend 10 minutes writing a script that takes 10 hours to run. C: spend 10 hours writing a script that takes 10 minutes to run
  1. Anonymous ★ Top Pick

    Python: spend 10 minutes writing a script that takes 10 hours to run. C: spend 10 hours writing a script that takes 10 minutes to run

  2. Anonymous

    Python is so readable even the quants ship it to prod - right up until the latency SLA hits, then it magically morphs into 10k lines of hand-rolled C extensions nobody claims ownership of

  3. Anonymous

    Python developers explaining to management why their data pipeline takes 3 hours: 'But think of all the time we saved not writing semicolons and managing memory!'

  4. Anonymous

    Python developers will spend three days optimizing their data pipeline with Cython and multiprocessing, only to realize the real bottleneck was a single unindexed database query. But hey, at least the code is readable enough that the next person can figure that out in five minutes instead of five hours - which is more than you can say for that 'performance-optimized' C codebase from 2003 that nobody dares touch because the original author documented it exclusively in Hungarian notation and regret

  5. Anonymous

    Python’s performance strategy is simple: push the hot path into NumPy/Cython, then benchmark the 90% glue while debating the GIL

  6. Anonymous

    Python: 10x easier to write, 10x slower to run - until the SLOs force that C interop hotpath rewrite

  7. Anonymous

    Python: easy to read, dominant in data science, and blazingly fast - right after you hand the hot loop to NumPy’s C while the GIL holds your coffee

  8. @RiedleroD 4y

    hmm

  9. @RiedleroD 4y

    what a coincidence

    1. @busy_hedgehog 4y

      memalloc

    2. @TERASKULL 4y

      oh yea because everyone here steals stale memes from reddit, deal with it

      1. @RiedleroD 4y

        idk I'm not finding it on reddit, must've cone from a different platform

        1. @TERASKULL 4y

          well the other platform stole from reddit cuz it's a highly upvoted post on r/programminghumor

          1. @RiedleroD 4y

            is it? I can't find it

            1. @TERASKULL 4y

              probably already taken down by the jannies, anyway I saw it yesterday

            2. @TERASKULL 4y

              nope, found it https://www.reddit.com/r/ProgrammerHumor/comments/p2fgpb/you_evil_people/

              1. @RiedleroD 4y

                damn, respect

                1. @RiedleroD 4y

                  I looked both in hot and top last week, but couldn't find it

  10. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

    Lol C is not even slow compared to other object oriented languages

    1. @RiedleroD 4y

      not at all, no

      1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

        Yeah its only slow if you compare it to asm but asm cant be compared to object oriented language

        1. @RiedleroD 4y

          rust is also slightly faster technically but really how fast your code runs comes down to how well you write it

          1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

            Well the overhead is the major thing that can be compared between stuff

            1. @RiedleroD 4y

              aye, Rust has 0 cost abstractions fyi 🙃

              1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                That sounds pretty good

        2. @anatoli26 4y

          C is not slow even compared to asm.. it all depends on how you write your code and how you compile it. If you build the project with the instrumented profiling stage first, I doubt you’d be able to write it faster in asm, provided you have the same skills in both languages. And if you target multiple CPU models (not even talking about different brands of the same arch, like Intel & AMD on amd64) I bet you won’t be able to outperform a well built C with asm, at least if the project is not a basic algo and you don’t have an infinite time to code it

          1. @RiedleroD 4y

            C still has overhead, compared to asm it's always slower

            1. @anatoli26 4y

              > It’s always slower No, it isn’t.. I was working in a HPC (high-performance computing) environment for 10 years, coding in C and asm by hand. You should know your CPU so so well to be able to code something in asm faster than a well-built C, that it’s almost impossible

              1. @RiedleroD 4y

                I mean perfect asm will always be better than perfect C obviously abstractions help massively with programming effectively

                1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                  Just make sure not to run this: {} - []

                  1. @RiedleroD 4y

                    not sure what that does

                    1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                      Because the opertor - automatically casts everything to numbers, and an empty array is false when converted to booleans and any object is a true if converted to booleans it will completely logically subtract 1 - 0 what then equals perfectly logically: -0

                      1. @RiedleroD 4y

                        so {}-[] is the same as -0, yes?

                        1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                          Yes

                          1. @RiedleroD 4y

                            why negative zero?

                            1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                              Best of all is I can clearly remember that in school we were taught that 0 has no sign at all

                              1. @RiedleroD 4y

                                same until we got to Mengenlehre (group theory I think?) where it's not in N+, but in N+0 (positive Natural numbers, positive Natural numbers and 0)

                                1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                                  Lol

                            2. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                              Ask the IEEE 754 standard

                              1. @RiedleroD 4y

                                but that's only for floats, no?

                                1. @RiedleroD 4y

                                  nvm it's js I remember

                                  1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                                    Yeah🤡

                                    1. @RiedleroD 4y

                                      glad I can use rust/wasm now, so I can decide between using a string, a string pointer or a string object which all have wildly different use cases

                                      1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

                                        Well C++ you can choose that too PLUS you can do it in w_char (unicode) or as normal ascii

                2. @anatoli26 4y

                  No..

                  1. @RiedleroD 4y

                    mate C literally compiles to asm, it can't be faster than that

                    1. @anatoli26 4y

                      I guess you don’t get the point.. the fact that C compiles to the same binary code that asm doesn’t make it slower.. to write proper asm code you should understand so much of the underlying CPU functioning, that today you can’t outsmart the compilers..

                      1. @RiedleroD 4y

                        I already told you, I'm not talking about practical performance. Ofc abstractions make it easier for the programmer to write good programs because there's a shitton of optimizations that can be applied to code that's often used, but are complicated as hell.

                        1. @anatoli26 4y

                          Then what are you talking about? 🤔

                          1. @RiedleroD 4y

                            reading comprehension. I already told you at least twice

                            1. @anatoli26 4y

                              You mean a theoretical abstract performance completely detached from the real world specifics? Like infinite knowledge and infinite coding time?

  11. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

    Is this sarcasm I dont get it exactly

  12. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

    This would be funnier if it would say "being slower that JavaScript" but idk if this would actually be true

    1. @RiedleroD 4y

      comes down to the task - technically, pure js is faster because it's been optimized to death, but python has heaps of built-in compiled libraries

      1. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

        Lol js is JIT compiled thats a huge overhead lol

  13. @anatoli26 4y

    And the best thing is that Rust can outperform C the same way C can outperform asm

    1. @RiedleroD 4y

      rust has less overhead than C, which makes it faster

      1. @anatoli26 4y

        Rust has C as the backend.. what do you mean? 🤔

        1. @RiedleroD 4y

          no it doesn't lol

          1. @RiedleroD 4y

            it compiles to asm just like any other compiled lang

            1. @feskow 4y

              afaik it compiles to llvm and then to asm

              1. @RiedleroD 4y

                asm is the end product, anyway, I don't know much about the intermediate process

                1. @anatoli26 4y

                  Asm is not the end product..

                  1. @RiedleroD 4y

                    asm as in the byte code, not the readable code

                    1. @anatoli26 4y

                      But asm has numerous stages to be “converted” to bytecode

                      1. @RiedleroD 4y

                        it's a direct analogue to what's in the bytecode

              2. @anatoli26 4y

                Yepp

  14. @anatoli26 4y

    And it’s not the matter of overhead in instructions.. if you have a L2 cache miss, it’s like 100 times (or even more) slower..

  15. @anatoli26 4y

    The nowadays compilers have much more information about what code does than the coder, except some simple algo. Have you tried instrumented profiling?

    1. @RiedleroD 4y

      > perfect asm read my message again. I was talking about theoretical maximum performance

      1. @anatoli26 4y

        Ok, but I’m talking about real projects.. in real life it’s almost impossible to outperform well-written C built with profiling

        1. @RiedleroD 4y

          nobody argued with that

  16. @anatoli26 4y

    There’s just no way you can have that amount of info to incorporate all the knowledge about real execution paths on real data that the compiler would gather

  17. @anatoli26 4y

    The abstract theory is another question..

  18. @anatoli26 4y

    With LLVM it compiles to an intermediate representation which would then have additional optimization stages. Same as if you write it in C with Clang

  19. @erabti 4y

    Great discussion 😊

    1. @RiedleroD 4y

      sorry, I'll stop

  20. @anatoli26 4y

    It’s just closer to bare-metal binary code than C, but that’s it, it’s not the binary code

  21. @anatoli26 4y

    It’s close enough I’d say.. also, the way it executes inside of the CPU is yet another question/issue..

  22. @RiedleroD 4y

    anyway, end of discussion, this won't lead us anywhere

    1. @MagnusEdvardsson 4y

      At least for me, this was very interesting. I wish I had teachers like Anatoli and you in college, discussing different points of view on the same subject.

      1. @RiedleroD 4y

        ah? well, I'm glad you liked the discussion, but I sure didn't :/ I often get myself into these debates despite not liking them.

        1. @RiedleroD 4y

          cause I'm stubborn and dislike being wrong, which is an unfortunate combo to have as an introvert

  23. @anatoli26 4y

    In this case yes, C code would be slower than asm code

  24. @anatoli26 4y

    But I’m not sure why would someone consider that

    1. @RiedleroD 4y

      just for fun - it's like comparing the top speed of cars. In the real world, they're never gonna reach that speed, but it's fun to compare them

      1. @anatoli26 4y

        Ok, for that case I agree. But if we see the practical performance aspects of different languages, then IMO Rust is the fastest one, then goes C and then asm. The constraints here are the limited knowledge of.. say.. a team of senior devs and a limited time they have to develop a real-world piece of software that works on real-world data supplied to it by real-world users..

        1. @RiedleroD 4y

          agreed, that definitely makes sense, although I think it's important to note that Rust is a lot newer than C which means there are less existing frameworks, which may hinder development. In any way C and Rust are very different languages, and I don't like to compare them directly in the context of real-world scenarios because I'm really not knowledgeable enough to do that.

          1. @anatoli26 4y

            😏 I guess today there’s much more tooling and really reusable libs in Rust than ever in the history of C. There was no single time that I couldn’t find some lib for a generic functionality like JSON parsing or a HTTPstand-alone server in https://lib.rs. In C the largest problem always was the lack of reusable (in practice) libs. The Rust crates is a godsent aspect of the language for C devs

  25. @MagnusEdvardsson 4y

    Hahaha. Don't take it personal, you are talking about theoretical programmers programming on theoretical processors. It doesn't get less personal than that. Also, I've seen Anatoli giving lectures in conventions, and he knows a shit-ton. It's always interesting challenging a knowledgeable person and understanding their reasoning.

  26. @anatoli26 4y

    The point here is that good C compliers like modern CLang/LLVM and gcc have more knowledge about the underlying hardware incorporated in them that a typical senior devs team would have. So it (the compiler) has a better understanding of how to translate the developers intentions into the bytecode, taking into account the cache sizes, the number of CPU pipelines and how the instructions are getting processed inside the CPU, to avoid stale pipelines, cache misses, etc that compared to say 2-3 additional asm instructions are 3-4 orders of magnitude bigger issues..

  27. @anatoli26 4y

    And if you perform an instrumented profiling of your C code, where the compiler instruments your code in order to collect the real-data execution paths metrics and then execute the binary on real-world data to collect the metrics, then recompile it feeding the compiler this statistics, that it would know about such situations that you couldn’t even suppose can happen. In this case it would be able to optimize the code even better, and except some really simple code like 10 lines of C, you won’t be able to outsmart the compiler

    1. @RiedleroD 4y

      didn't even know compilers could take metrics into account, you learn something new every day I guess

      1. @anatoli26 4y

        https://en.m.wikipedia.org/wiki/Profile-guided_optimization

        1. @RiedleroD 4y

          thanks for the link, I'll bookmark it to read tomorrow morning

      2. @anatoli26 4y

        I was working in HPC projects asm hand-coding for about 8 years (around 2004), for IBM BlueGene/L supercomputer and x86 megaclusters of 500+ nodes.. was holding the details of almost the entire Intel Instructions Set in brain.. but then SSE instructions appeared, caches got bigger, more CPU pipelining and smarter CPU tricks to execute the instructions.. so to outsmart the compiler with profile-guided optimizations became a task not worth the effort.. say 5% faster spending months on performance tuning the project.. and then the compilers became even smarter, the CPUs even more complex so I quit the asm performance tuning as it made no sense

        1. @RiedleroD 4y

          ah, see, I didn't have time in 2004 as I was busy being born lol Respect, man, sounds like you're an elite professional.

          1. @anatoli26 4y

            😆 thanks

  28. @RiedleroD 4y

    damn I can't keep up with your walls of text 😅

  29. Deleted Account 4y

    basically it's not all that clear now

    1. Deleted Account 4y

      to get good perf you actually have to use quite alot of unsafe, risking ub

      1. Deleted Account 4y

        also, compared to c++ rust's meta sucks

      2. @anatoli26 4y

        Why so? Do you have a link to read about the details?

        1. Deleted Account 4y

          consider this example: suppose you have a function that fails very rarely, the rust way is to make that function return a Result, but that actually incurs a cost on the happy path, bc you have to have an if even if your Result is Ok, on the other hand, if you user exceptions, you can avoid that if and save time on the happy path

          1. Deleted Account 4y

            also there are times where you have to perform runtime checks to ensure safety, bc rust's type system sucks, whereas in c++ you could just make it not compile

          2. @feskow 4y

            But exceptions are not free either

            1. Deleted Account 4y

              yeah, it's a tradeoff

              1. Deleted Account 4y

                better to have both

          3. @anatoli26 4y

            But the “if” is just a single tick if you guess the result, do you know that?

            1. Deleted Account 4y

              i know that, but it's worse than none

              1. @anatoli26 4y

                Also a single tick doesn’t matter at all if it’s not inside some absolutely EPIC cycle, and you’re talking about saving it on func exit, that implies a number of stack reads, which could result in cache misses, so your tick is just lost in the cache misses delays and pipeline stales causing hundreds of ticks delay..

                1. Deleted Account 4y

                  the question is when

          4. @anatoli26 4y

            👆you say that the Rust way to check the result is inefficient and you should recure to unsafe Rust to "fix" it

            1. Deleted Account 4y

              nope, that's not at all what i told

              1. Deleted Account 4y

                i told that you want both options

  30. @anatoli26 4y

    With respect to Rust outperforming C, the point here is that the Rust compiler has much more knowledge about your intentions that if you write the code in C, so it can make assumptions the C compiler can’t. And with these assumptions it can optimize it even further. On the other hand, it’s much easier to write performant code in Rust than in C, not to say that in C you just never have time for the optimizations as your are constantly debugging it investigating strange crushes, especially when multithreading and coding non-trivial stuff

  31. @anatoli26 4y

    So in practical terms your real-world Rust code is almost guaranteed to outperform your real-world C code

  32. @anatoli26 4y

    If you haven’t seen it yet, I suggest you check this short online book about Rust performance tuning: https://nnethercote.github.io/perf-book/

  33. @anatoli26 4y

    😄 yeah Rust was godsent to the C devs that were suffering for decades..

  34. @anatoli26 4y

    now life is great again

  35. @anatoli26 4y

    I mean, under no circumstances would I make my code that ugly to save a single tick!

    1. Deleted Account 4y

      as of today, you don't have an option

      1. Deleted Account 4y

        even if you liked to

  36. @anatoli26 4y

    If you have a single cache miss its like 150 ticks

  37. @anatoli26 4y

    If you stale the pipeline with some unordered instruction it could lead to multiple cache misses

  38. @anatoli26 4y

    I just trust the compiler to handle all that stuff.. you never win by saving a tick.. been there, quit it

    1. Deleted Account 4y

      it's a small example that i thought up off the top of my head

      1. Deleted Account 4y

        btw, on the topic of error handling, tho it's more about expressiveness and not perf: why isn't there a std::variant analog in rust? you literally can't live without it in result based error handling world

  39. @anatoli26 4y

    I mean this is not the way you optimize your code

  40. @anatoli26 4y

    The 2 most critical performance issues on the CPU level are the cache misses and the pipeline stales

    1. Deleted Account 4y

      with exceptions, when do they happen?

      1. Deleted Account 4y

        they happen only on the sad path, not on the happy one

        1. @anatoli26 4y

          Have you ever coded in asm?

          1. Deleted Account 4y

            yes

            1. @anatoli26 4y

              Then what do you mean about the things happening on a happy path and not happening in the sad path?

              1. Deleted Account 4y

                when exception is/is not thrown

                1. @anatoli26 4y

                  How do you implement a condition check in asm?

                  1. Deleted Account 4y

                    with a conditional jump (eg. jne), cmov may actually be an option sometimes too

                    1. @anatoli26 4y

                      If the result is in eax and 0 means no errors, the code would be: test eax, eax jnz error_handling

                      1. Deleted Account 4y

                        yes, callee side, but caller side ou don't have to do anything

                  2. Deleted Account 4y

                    oh fuck, a test, not a branch

                    1. Deleted Account 4y

                      there is a test instruction, and arithmetic ops write to the flag register too

                  3. Deleted Account 4y

                    https://gcc.godbolt.org/z/Thh8YcWaT an example

      2. @anatoli26 4y

        Exceptions are on the much higher level, in the C code.. but as you’re talking about saving a single if which is a conditional jump in asm like (je/jz) which’s is 1 tick (CPU cycle) on right guess and 3 ticks on wrong guess (right means you specify it in such a way that most of the times the jump is not performed), I’m showing you the underlying considerations worth much more than trying to save a single if.

        1. @anatoli26 4y

          And as it was pointed before, exceptions are basically the same ifs, but more complex on the asm instructions level, so it’s not clear what would be faster.. a simple je (if in asm) or some non-trivial exceptions checking

  41. @anatoli26 4y

    Check here for relative latenixes of cache misses: https://stackoverflow.com/questions/1126529/what-is-the-cost-of-an-l1-cache-miss#29188516

    1. Deleted Account 4y

      oh, i remembered one more thing: allocating a large object on the heap involves memcpying it off the stack first

      1. Deleted Account 4y

        well, all objects, but this matters for the particularly large ones

  42. @anatoli26 4y

    Are you sure you fully understand this stuff?

  43. Deleted Account 4y

    well, unless you actually intend on handling the error

  44. @anatoli26 4y

    You always have to make a check.. if not, you can’t know if you have an error condition or not

    1. Deleted Account 4y

      look at the example

      1. @anatoli26 4y

        So compare the code you suggest of an exception: thrw(bool) [clone .cold]: .L3: mov edi, 4 call __cxa_allocate_exception xor edx, edx mov esi, OFFSET FLAT:_ZTIi mov DWORD PTR [rax], 43 mov rdi, rax call __cxa_throw with a result check code: test eax, eax jnz error_handling and tell me what's faster

        1. Deleted Account 4y

          do you see the cold

          1. Deleted Account 4y

            didn't i already tell you that it's efficient only when errors are rare?

    2. Deleted Account 4y

      you can even turn off the optimizations and see that there is a call and then an immediate leave

    3. Deleted Account 4y

      well, actually, afaik rust already uses this mechanism for unwind panics

      1. @anatoli26 4y

        unwind panics are entirely different stuff that what was your initial suggestion for optimization

        1. Deleted Account 4y

          they are the same mechanism

  45. @anatoli26 4y

    same mechanism as the C exceptions, but you proposed another thing initially

    1. Deleted Account 4y

      c exceptions?

  46. @anatoli26 4y

    And I'm saying that a simple result check is just 1 tick of the CPU time

  47. @anatoli26 4y

    a simple results check is the least expensive option of all

    1. Deleted Account 4y

      you simply refuse to see that sth like ? operator is free as in no if with exceptions

      1. @anatoli26 4y

        🤔 could you please provide the asm code for both cases? I guess I don't understand what you mean..

        1. Deleted Account 4y

          https://gcc.godbolt.org/z/TYWMEKPco here, with one more fnction

          1. Deleted Account 4y

            look at thrw2, see no if

            1. @anatoli26 4y

              what do you mean no if? I don't understand what you propose.. i.e. there is a func in rust that returns something as a Result and you should check it for errors in the outer function.. this would be as simple as: test eax, eax jnz error_handling

              1. Deleted Account 4y

                https://gcc.godbolt.org/z/K3zvMKn6n

                1. Deleted Account 4y

                  wait no, it's not good yet

  48. @anatoli26 4y

    no RAM involved, no cache misses

  49. @anatoli26 4y

    then you suggest a huge and complex code with function calls that involve writing to RAM invalidating your caches, which implies cache misses, etc.. and you're saying it's faster? don't understand your point

    1. Deleted Account 4y

      it's only in rare cases, i repeat

    2. Deleted Account 4y

      look at res2 now

  50. @anatoli26 4y

    do you mean this code is fast?

    1. Deleted Account 4y

      https://gcc.godbolt.org/z/1118bMj9K added math to illustrate a point

      1. @anatoli26 4y

        and what would be the equivalent in Rust?

        1. Deleted Account 4y

          https://gcc.godbolt.org/z/M54rzeMnr

          1. Deleted Account 4y

            now take a look at res2 vs thrw2

            1. Deleted Account 4y

              also take a look at that cmov, which will never be just 1 tick

          2. @anatoli26 4y

            add there a main, call there the necessary func and let's see the total cost of execution in both cases

            1. Deleted Account 4y

              well, i'll leave it as an excersise for you, as i am alre in bed

              1. @anatoli26 4y

                😆 thanks, done those exercises 25 years ago

  51. @anatoli26 4y

    write its alternative in Rust and compare

  52. @anatoli26 4y

    if you can't see the clear difference in favor of Rust from your own examples, the only thing that can help is if you calculate the total cost of execution of your examples and compare 2 numbers

    1. Deleted Account 4y

      ofc if the probability of that bool being false is 50% then ofc rust wins, but if it's more like 0.1% then you better bet c++ will win

      1. @anatoli26 4y

        just add main() to Rust, in both Rust and C put there a loop of say 1M iterations of calling the func you want to prove, then compile and run both binaries and see the result

  53. @anatoli26 4y

    run them this way: $ time rust_bin and $ time c_bin

    1. Deleted Account 4y

      that won't work tho

      1. Deleted Account 4y

        now tell me why just time won't work

  54. @anatoli26 4y

    you say it won't work, you say why it won't work

    1. Deleted Account 4y

      a question: does a program really start in main?

      1. @anatoli26 4y

        are you running a basic asm quiz?

        1. Deleted Account 4y

          no asm

          1. Deleted Account 4y

            you don't have to know it to answer

            1. Deleted Account 4y

              and answer why that won't work

              1. @anatoli26 4y

                i've already spent toooooo much time discussing with you that basic stuff.. if you want to prove your point, provide here the same code in both C and Rust that compiles and runs without fixing it.. and we'll see the results

                1. Deleted Account 4y

                  now

  55. @beton_kruglosu_totchno 4y

    what was the disputed claim? holy fuck

  56. @deerspangle 4y

    Funniest part was looking at this meme and seeing "197 comments"

  57. Deleted Account 4y

    take a look at theese srcs

    1. Deleted Account 4y

      need your confirmation fefore i reveal the numbers

  58. @anatoli26 4y

    using vec for a for loop..

    1. Deleted Account 4y

      otherwise it's inlined away, and to be fair it's done in c++ and rust equally

  59. @anatoli26 4y

    this makes the program like 100 times (or more) slower

  60. @anatoli26 4y

    i don't have time right now, but just for fun, this weekend I'll send you a correctly coded rust code

  61. @anatoli26 4y

    Vec for loop is q is a construct known to be extremely slow compared yo a simple int loop

    1. Deleted Account 4y

      I don't have an int loop in c++ tho

      1. @anatoli26 4y

        Are you testing the Result handling performance or a vec enumeration performance??

        1. Deleted Account 4y

          vec iteration is only there to prevent inlining, if you have a better idea be my guest

  62. @anatoli26 4y

    And BTW your code is extremely convoluted.. all the time counting code should not be there

    1. Deleted Account 4y

      are you sure you don't want to compare allocation performance?

  63. @anatoli26 4y

    90% of what you put in the cpp is not needed

  64. @anatoli26 4y

    You claimed that the Result check is slower than exceptions

  65. @anatoli26 4y

    So let’s check your claim first

  66. @anatoli26 4y

    Then you can make a new claim and we’ll see if you’re right or not

  67. @anatoli26 4y

    The thing is simple: you make a for loop with ints in both cases and put there the check

    1. Deleted Account 4y

      this is also compiled away

  68. @anatoli26 4y

    It doesn’t matter how the loop ends implemented in bytecode, we are not testing the loop, it’s just to repeat the same check many times as a single check won’t show the difference

    1. Deleted Account 4y

      it caches the result and compiles away the loop entierly

  69. @anatoli26 4y

    And it also doesn’t matter the inlining.. we are testing the default compilation without anything special about it.. cc x.cpp and rustc main.rs

    1. Deleted Account 4y

      so no optimizations?

      1. @anatoli26 4y

        Exactly, no special optimizations (but the code do should be well written, i.e. with known good constructs), no pragmas, inlines & co, just the basic code of try/catch vs Result check and a basic int loop for enough iterations for the execution to last for some 5 seconds to make the process start statistically negligible

        1. Deleted Account 4y

          did you try to read unoptimized rust?

  70. @anatoli26 4y

    The most simple code in both cases

  71. @anatoli26 4y

    Should be like 10 lines of code at most

  72. @anatoli26 4y

    So when you measure the time with time the measurement is just of the loop itself

    1. Deleted Account 4y

      rust 0.38s user 0.00s system 99% cpu 0.385 total cpp 0.04s user 0.00s system 99% cpu 0.048 total which is bs bc why the fuck would you want all optimizations off in the first place

Use J and K for navigation