Intro to C++ and Rust: Just Enough to Read the Fast Code Under AI A tutorial post demonstrates how to read C++ and Rust code underlying AI libraries such as NumPy (written in C), PyTorch (C++ plus CUDA), Hugging Face tokenizers (Rust), llama.cpp (C and C++), Polars (Rust), Pydantic version 2 (Rust core), and Ruff and uv (Rust), arguing that Python orchestrates the work while compiled languages do the heavy lifting. The author compiled the C++ examples with g++ 13 on Ubuntu 24.04 but did not compile the Rust snippets, which the post labels standard idioms to verify before trusting. The post frames native code as a last resort after better algorithms, existing libraries, and NumPy vectorization, and notes that step can still disappoint. Python is the language of AI, but it isn't the language doing the heavy lifting. Underneath NumPy, PyTorch, and many tools you'll use sits C, C++, Rust, and CUDA. You don't need to master them, but you should be able to read them. This post is optional, and it's about reading, not writing. By the end you'll recognize the main features of C++ and Rust code, understand why native code is fast and when it isn't , and have called a C++ function from Python yourself. A note on what I ran. The C++ code was compiled with g++ 13 on Ubuntu 24.04, and the outputs and compiler messages are real. I had no Rust toolchain in my test environment, so the Rust snippets are standard idioms that I did not compile. Treat them as reading material, and compile them yourself before trusting them. Why the fast parts aren't written in Python Back in Post 15, we saw that Python's flexibility costs speed, and that libraries get around it by doing the heavy work in compiled code while Python just gives the orders. Some well-known examples: | Project | What it is | Core written in | |---|---|---| | NumPy | Arrays and math | C | | PyTorch | Deep learning | C++ plus CUDA for GPUs | | Hugging Face tokenizers | Fast tokenization | Rust | | llama.cpp | Running language models locally | C and C++ | | Polars | Data frames | Rust | | Pydantic version 2 | Data validation | Rust core | | Ruff and uv | A linter, and a package manager | Rust | So when you hit a confusing bug or a performance mystery inside one of these, the answer often lives in code that isn't Python. Reading it won't be your daily job, but being able to will set you apart. You'll rarely need to write it. The ladder from Post 15 still applies: a better algorithm first, then a library that already does the job, then NumPy vectorization, and only then native code. As you'll see below, even that last step can disappoint. What's different about C++ and Rust Three differences explain almost everything that feels strange: 1. They're compiled. You don't run the source directly. A compiler translates it into machine code first, and it refuses to build if it finds certain mistakes. That's why a type error stops you before the program runs. 2. Types are fixed, and written out. Every variable has a declared type int , float , std::string , and it can't change. 3. You think about memory. In Python, memory is looked after for you Post 15 . In C++ and Rust you decide who owns data, and who may look at it or change it. | | Python | C++ | Rust | |---|---|---|---| | Typing | Dynamic | Static | Static | | Memory | Automatic | You manage it modern C++ helps a lot | The compiler enforces rules | | Mistakes like out-of-range access | Raise an error | Can silently misbehave | Caught, or panic safely | | Build tool | none / pip , uv | g++ , make , CMake | cargo | | Learning curve | Gentle | Wide and old, with a lot of history | Steep at first, strict compiler | Reading C++ Here's the cycle. You write file.cpp , compile it, and run the result: g++ -std=c++20 -Wall -Wextra -O2 basics.cpp -o basics ./basics -Wall -Wextra turns on helpful warnings, and -O2 turns on optimization, which matters a great deal more on that below . Here's a program that packs in most of the syntax you'll meet when reading AI code. Skim it first, and then I'll explain the cues: include