{"id":2937,"date":"2025-04-08T07:02:36","date_gmt":"2025-04-08T07:02:36","guid":{"rendered":"https:\/\/mailitics.com\/index.php\/2025\/04\/08\/how-to-optimize-your-python-program-for-slowness\/"},"modified":"2025-04-08T07:02:36","modified_gmt":"2025-04-08T07:02:36","slug":"how-to-optimize-your-python-program-for-slowness","status":"publish","type":"post","link":"https:\/\/mailitics.com\/index.php\/2025\/04\/08\/how-to-optimize-your-python-program-for-slowness\/","title":{"rendered":"How to Optimize your Python Program for Slowness"},"content":{"rendered":"<p>    How to Optimize your Python Program for Slowness<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n    <!-- no image --><br \/>\n \t<BR><br \/>\n<BR><\/BR><\/p>\n<div>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Also available: A <a href=\"https:\/\/medium.com\/@carlmkadie\/how-to-optimize-your-rust-program-for-slowness-eb2c1a64d184\">Rust version of this article.<\/a><\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\"><mdspan datatext=\"el1744071663872\" class=\"mdspan-comment\">Everyone<\/mdspan> talks about making Python programs faster [<a href=\"https:\/\/www.infoworld.com\/article\/3855600\/making-python-faster-wont-be-easy-but-itll-be-worth-it.html\">1<\/a>,<a href=\"https:\/\/medium.com\/data-science\/gpu-optional-python-be36a02b634d\"> 2<\/a>,<a href=\"https:\/\/www.kdnuggets.com\/2021\/06\/make-python-code-run-incredibly-fast.html\"> 3<\/a>], but what if we pursue the opposite goal? Let\u2019s explore how to make them slower\u200a\u2014\u200a<strong>absurdly slower<\/strong>. Along the way, we\u2019ll examine the nature of computation, the role of memory, and the scale of unimaginably large numbers.<\/p>\n<p class=\"wp-block-paragraph\">Our guiding challenge: <strong>write short Python programs that run for an extraordinarily long time.<\/strong><\/p>\n<p class=\"wp-block-paragraph\">To do this, we\u2019ll explore a sequence of rule sets\u200a\u2014\u200aeach one defining what kind of programs we\u2019re allowed to write, by placing constraints on halting, memory, and program state. This sequence isn\u2019t a progression, but a series of shifts in perspective. Each rule set helps reveal something different about how simple code can stretch time.<\/p>\n<h4 class=\"wp-block-heading\"><strong>Here are the rule sets we\u2019ll investigate:<\/strong><\/h4>\n<ol class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">\n<strong>Anything Goes<\/strong>\u200a\u2014\u200aInfinite Loop<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Must Halt, Finite Memory<\/strong>\u200a\u2014\u200aNested, Fixed-Range Loops<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Infinite, Zero-Initialized Memory<\/strong>\u200a\u2014\u200a5-State Turing Machine<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Infinite, Zero-Initialized Memory<\/strong>\u200a\u2014\u200a6-State Turing Machine (&gt;10\u2191\u219115 steps)<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Infinite, Zero-Initialized Memory<\/strong>\u200a\u2014\u200aPlain Python (compute 10\u2191\u219115 without Turing machine emulation)<\/li>\n<\/ol>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Aside: 10\u2191\u219115 is not a typo or a double exponent. It\u2019s a number so large that \u201cexponential\u201d and \u201castronomical\u201d don\u2019t describe it. We\u2019ll define it in <strong>Rule Set 4.<\/strong><\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">We start with the most permissive rule set. From there, we\u2019ll change the rules step by step to see how different constraints shape what long-running programs look like\u200a\u2014\u200aand what they can teach us.<\/p>\n<h2 class=\"wp-block-heading\">Rule Set 1: Anything Goes\u200a\u2014\u200aInfinite Loop<\/h2>\n<p class=\"wp-block-paragraph\">We begin with the most permissive rules: the program doesn\u2019t need to halt, can use unlimited memory, and can contain arbitrary code.<\/p>\n<p class=\"wp-block-paragraph\">If our only goal is to run forever, the solution is immediate:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">while True:\n\u00a0 pass<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This program is short, uses negligible memory, and never finishes. It satisfies the challenge in the most literal way\u200a\u2014\u200aby doing nothing forever.<\/p>\n<p class=\"wp-block-paragraph\">Of course, it\u2019s not interesting\u200a\u2014\u200ait does nothing. But it gives us a baseline: if we remove all constraints, infinite runtime is trivial. In the next rule set, we\u2019ll introduce our first constraint: <strong>the program must eventually halt.<\/strong> Let\u2019s see how far we can stretch the running time under that new requirement\u200a\u2014\u200ausing only <strong>finite memory<\/strong>.<\/p>\n<h2 class=\"wp-block-heading\">Rule Set 2: Must Halt, Finite Memory\u200a\u2014\u200aNested, Fixed-Range Loops<\/h2>\n<p class=\"wp-block-paragraph\">If we want a program that runs longer than the universe will survive <em>and then halts<\/em>, it\u2019s easy. Just write two nested loops, each counting over a fixed range from 0 to 10\u00b9\u2070\u2070\u22121:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">for a in range(10**100):\n  for b in range(10**100):\n      if b % 10_000_000 == 0:\n          print(f\"{a:,}, {b:,}\")<\/code><\/pre>\n<p class=\"wp-block-paragraph\">You can see that this program halts after 10\u00b9\u2070\u2070 \u00d7 10\u00b9\u2070\u2070 steps. That\u2019s 10\u00b2\u2070\u2070. And\u200a\u2014\u200aignoring the print\u2014this program uses only a small amount of memory to hold its two integer loop variables\u2014just 144 bytes.<\/p>\n<p class=\"wp-block-paragraph\">My desktop computer runs this program at about 14 million steps per second. But suppose it could run at <a href=\"https:\/\/en.wikipedia.org\/wiki\/Planck_units#Planck_time\">Planck speed<\/a> (the smallest meaningful unit of time in physics). That would be about 10\u2075\u2070 steps per year\u200a\u2014\u200aso 10\u00b9\u2075\u2070 years to complete.<\/p>\n<p class=\"wp-block-paragraph\">Current cosmological models estimate <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_dates_predicted_for_apocalyptic_events#Scientific_far_future_predictions\">the heat death of the universe<\/a> in 10\u00b9\u2070\u2070 years, so our program will run about 100,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 times longer than the projected lifetime of the universe.<\/p>\n<p class=\"wp-block-paragraph\"><em>Aside: Practical concerns about running a program beyond the end of the universe are outside the scope of this article.<\/em><\/p>\n<p class=\"wp-block-paragraph\">For an added margin, we can use more memory. Instead of 144 bytes for variables, let\u2019s use 64 gigabytes\u200a\u2014\u200aabout what you\u2019d find in a well-equipped personal computer. That\u2019s about 500 million times more memory, which gives us about one billion variables instead of 2. If each variable iterates over the full 10\u00b9\u2070\u2070 range, the total number of steps becomes roughly 10\u00b9\u2070\u2070^(10\u2079), or about 10^(100 billion) steps. At Planck speed\u200a\u2014\u200aroughly 10\u2075\u2070 steps per year\u200a\u2014\u200athat corresponds to 10^(100 billion \u2212 50) years of computation.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dotted\">\n<p class=\"wp-block-paragraph\">Can we do better? Well, if we allow an unrealistic but interesting rule change, we can do much, much better.<\/p>\n<h2 class=\"wp-block-heading\">Rule Set 3: Infinite, Zero-Initialized Memory\u200a\u2014\u200a5-State Turing Machine<\/h2>\n<p class=\"wp-block-paragraph\">What if we allow infinite memory\u200a\u2014\u200aso long as it starts out entirely zero?<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Aside:<\/strong> Why don\u2019t we allow infinite, arbitrarily initialized memory? Because it trivializes the challenge. For example, you could mark a single byte far out in memory with a<code> 0x01<\/code>\u2014say, at position 10\u00b9\u00b2\u2070\u2014and write a tiny program that just scans until it finds it. That program would take an absurdly long time to run\u200a\u2014\u200abut it wouldn\u2019t be interesting. The slowness is baked into the data, not the code. We\u2019re after something deeper: small programs that generate their own long runtimes from simple, uniform starting conditions.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">My first idea was to use the memory to count upward in binary:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-tsx\">0\n1\n10\n11\n100\n101\n110\n111\n...<\/code><\/pre>\n<p class=\"wp-block-paragraph\">We can do that\u200a\u2014\u200abut how do we know when to stop? If we don\u2019t stop, we\u2019re violating the \u201cmust halt\u201d rule. So, what else can we try?<\/p>\n<p class=\"wp-block-paragraph\">Let\u2019s take inspiration from the father of <a href=\"https:\/\/towardsdatascience.com\/tag\/computer-science\/\" title=\"Computer Science\">Computer Science<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Alan_Turing\"><strong>Alan Turing<\/strong><\/a>. We\u2019ll program a simple abstract machine\u200a\u2014\u200anow known as a <strong>Turing machine<\/strong>\u200a\u2014\u200aunder the following constraints:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The machine has <strong>infinite memory<\/strong>, laid out as a tape that extends endlessly in both directions. Each <strong>cell<\/strong> on the tape holds a single bit: 0 or 1.<\/li>\n<li class=\"wp-block-list-item\">A read\/write head moves across the tape. On each step, it <strong>reads<\/strong> the current bit, <strong>writes<\/strong> a new bit (0 or 1), and <strong>moves<\/strong> one cell <strong>left or right<\/strong>.<\/li>\n<\/ul>\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/tape1.png?ssl=1\" alt=\"\" class=\"wp-image-601221\"><figcaption class=\"wp-element-caption\">A read\/write head positioned on an infinite tape.<\/figcaption><\/figure>\n<h5 class=\"wp-block-heading\"><\/h5>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The machine also has an internal variable called <strong>state<\/strong>, which can hold one of <em>n<\/em> values. For example, with 5 states, we might name the possible values A, B, C, D, and E\u2014plus a special halting state H, which we don\u2019t count among the five. The machine always starts in the first state, A.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">We can express a full Turing machine program as a transition table. Here\u2019s an example we\u2019ll walk through step by step.<\/p>\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/program1.png?ssl=1\" alt=\"\" class=\"wp-image-601222\"><figcaption class=\"wp-element-caption\">A 5-state Turing machine transition table.<\/figcaption><\/figure>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Each <strong>row<\/strong> corresponds to the current <strong>tape value<\/strong> (0 or 1).<\/li>\n<li class=\"wp-block-list-item\">Each <strong>column<\/strong> corresponds to the current <strong>state<\/strong> (A through E).<\/li>\n<li class=\"wp-block-list-item\">Each entry in the table tells the machine what to do next:\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The <strong>first character<\/strong> is the <strong>bit to write<\/strong> (0 or 1)<\/li>\n<li class=\"wp-block-list-item\">The second is the direction to move (L for left, R for right)<\/li>\n<li class=\"wp-block-list-item\">The <strong>third<\/strong> is the<strong> next state to enter <\/strong>(A, B, C, D, E, or H, where H is the special halting state).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Now that we\u2019ve defined the machine, let\u2019s see how it behaves over time.<\/p>\n<p class=\"wp-block-paragraph\">We\u2019ll refer to each moment in time\u200a\u2014\u200athe full configuration of the machine and tape\u200a\u2014\u200aas a <strong>step<\/strong>. This includes the current tape contents, the head position, and the machine\u2019s internal state (like A, B, or H).<\/p>\n<p class=\"wp-block-paragraph\">Below is <strong>Step 0<\/strong>. The head is pointing to a 0 on the tape, and the machine is in <strong>state <\/strong>A.<\/p>\n<p class=\"wp-block-paragraph\">Looking at <strong>row 0, column A<\/strong> in the program table, we find the instruction 1RB. That means:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Write 1 to the current tape cell.<\/li>\n<li class=\"wp-block-list-item\">Move the head <strong>Right.<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">Enter <strong>state <\/strong>B.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Step 0:<\/strong><\/p>\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/step0.png?ssl=1\" alt=\"\" class=\"wp-image-601223\"><\/figure>\n<p class=\"wp-block-paragraph\">This puts us in <strong>Step 1<\/strong>:<\/p>\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/step1.png?ssl=1\" alt=\"\" class=\"wp-image-601224\"><\/figure>\n<p class=\"wp-block-paragraph\">The machine is now in <strong>state <\/strong>B, pointing at the next tape cell (again 0).<\/p>\n<p class=\"wp-block-paragraph\">What will happen if we let this Turing machine keep running? It will run for exactly <strong>47,176,870 steps<\/strong>\u200a\u2014\u200aand then halt.\u00a0<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Aside: With a Google sign in, you can run this yourself via a <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\/blob\/main\/notebooks\/turing_machines.ipynb\">Python notebook on Google Colab<\/a>. Alternatively, you can copy and run the notebook locally on your own computer by <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\/blob\/main\/notebooks\/turing_machines.ipynb\">downloading it from GitHub<\/a>.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">That number 47,176,870<strong> <\/strong>is astonishing on its own, but seeing the full run makes it more tangible. We can visualize the execution using a <strong>space-time diagram<\/strong>, where each row shows the tape at a single step, from top (earliest) to bottom (latest). In the image:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The first row is blank\u200a\u2014\u200ait shows the all-zero tape before the machine takes its first step.<\/li>\n<li class=\"wp-block-list-item\">1s are shown in <strong>orange.<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">0s are shown in <strong>white.<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Light orange<\/strong> appears where 0s and 1s are so close together they blend.<\/li>\n<\/ul>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"959\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/bb5-1024x959.png?resize=1024%2C959&#038;ssl=1\" alt=\"\" class=\"wp-image-601225\"><figcaption class=\"wp-element-caption\">Space-time diagram for the champion 5-state Turing machine. It runs for 47,176,870 steps before halting. Each row shows the tape at a single step, starting from the top. Orange represents 1, white represents 0.<\/figcaption><\/figure>\n<h5 class=\"wp-block-heading\"><\/h5>\n<p class=\"wp-block-paragraph\">In 2023, an online group of amateur researchers organized through <a href=\"https:\/\/bbchallenge.org\/\"><strong>bbchallenge.org<\/strong><\/a> proved that this is the <a href=\"https:\/\/www.quantamagazine.org\/amateur-mathematicians-find-fifth-busy-beaver-turing-machine-20240702\/\"><strong>longest-running 5-state Turing machine<\/strong><\/a> that eventually halts.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dotted\">\n<p class=\"wp-block-paragraph\">Want to see this Turing machine in motion? You can watch the full 47-million-step execution unfold in this <strong>pixel-perfect video<\/strong>:<\/p>\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\">\n<div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Turing Machine Busy Beaver 5 Champ--47,176,870 Steps--Perfect Pixel Binning\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/fPGg4kwwkGg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div>\n<\/figure>\n<p class=\"wp-block-paragraph\">Or interact with it directly using the <a href=\"https:\/\/carlkcarlk.github.io\/busy_beaver_blaze\/v0.2.5\/index.html#program=bb5&amp;run=true\"><strong>Busy Beaver Blaze<\/strong><\/a> web app.<\/p>\n<p class=\"wp-block-paragraph\">The video generator and web app are part of <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\/\">busy-beaver-blaze<\/a>, the open-source <a href=\"https:\/\/towardsdatascience.com\/tag\/python\/\" title=\"Python\">Python<\/a> &amp; Rust project that accompanies this article.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dotted\">\n<p class=\"wp-block-paragraph\">It\u2019s hard to believe that such a small machine can run <strong>47 million steps<\/strong> and still halt. But it gets even more astonishing: the team at <a href=\"http:\/\/bbchallenge.org\/\">bbchallenge.org<\/a> found a <strong>6-state machine<\/strong> with a runtime so long it can\u2019t even be written with ordinary exponents.<\/p>\n<h2 class=\"wp-block-heading\">Rule Set 4: Infinite, Zero-Initialized Memory\u200a\u2014\u200a6-State Turing Machine (&gt;10\u2191\u219115 steps)<\/h2>\n<p class=\"wp-block-paragraph\">As of this writing, the longest running (but still halting) 6-state Turing machine known to humankind is:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">A   B   C   D   E   F\n0   1RB 1RC 1LC 0LE 1LF 0RC\n1   0LD 0RF 1LA 1RH 0RB 0RE<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Here is a video showing its <strong>first 10 trillion steps:<\/strong><\/p>\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\">\n<div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Busy Beaver 6 Contender--10 Trillion Steps--Perfect Pixel Binning\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/qYi5_mNLppY?start=1&amp;feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div>\n<\/figure>\n<p class=\"wp-block-paragraph\">And here you can <a href=\"https:\/\/carlkcarlk.github.io\/busy_beaver_blaze\/v0.2.5\/index.html#run=true\">run it interactively via a web app<\/a>.<\/p>\n<p class=\"wp-block-paragraph\">So, if we are patient\u200a\u2014\u200acomically patient\u200a\u2014\u200ahow long will this Turing machine run? More than 10\u2191\u219115 where \u201c10 \u2191\u2191 15\u201d means:<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXe2ZHW_xNiIrPTg-5-Jbdmv6gv6lb0tysfy4AVnQRhbjmjjGV6snGYlz5ar6mzTZNVrlenPKQdGxfzZQvlzeZZmZzZFOrhcfq0q1ZzZz5VDMyTvQwzbTFdIuV1yC8pZbQF-ii7F?key=hvOowKrRIeVu9DCejPGzg0wy\" alt=\"\"><\/figure>\n<p class=\"wp-block-paragraph\">This is <strong>not<\/strong> the same as 10\u00b9\u2075 (which is just a regular exponent). Instead:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">10\u00b9 = 10<\/li>\n<li class=\"wp-block-list-item\">10\u00b9\u2070 = 10,000,000,000<\/li>\n<li class=\"wp-block-list-item\">10^10^10 is 10\u00b9\u2070\u2070\u2070\u2070\u2070\u2070\u2070\u2070\u2070\u2070, already unimaginably large.<\/li>\n<li class=\"wp-block-list-item\">10\u2191\u21914 is so large that it vastly exceeds the number of atoms in the observable universe.<\/li>\n<li class=\"wp-block-list-item\">10\u2191\u219115 is so large that writing it in exponent notation becomes annoying.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Pavel Kropitz announced this 6-state machine on May 30, 2022. Shawn Ligocki has <a href=\"https:\/\/www.sligocki.com\/2022\/06\/21\/bb-6-2-t15.html\">a great write up<\/a> explaining both his and Pavel\u2019s discoveries. To prove that these machines run so long and then halt, researchers used a mix of analysis and automated tools. Rather than simulating every step, they identified repeating structures and patterns that could be proven\u200a\u2014\u200ausing formal, machine-verified proofs\u200a\u2014\u200ato eventually lead to halting.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dotted\">\n<p class=\"wp-block-paragraph\">Up to this point, we\u2019ve been talking about Turing machines\u200a\u2014\u200aspecifically, the longest-known 5- and 6-state machines that eventually halt. We ran the 5-state champion to completion and watched visualizations to explore its behavior. But the discovery that it\u2019s the longest halting machine with 5 states\u200a\u2014\u200aand the identification of the 6-state contender\u200a\u2014\u200acame from extensive research and formal proofs, not from running them step-by-step.<\/p>\n<p class=\"wp-block-paragraph\">That said, the Turing machine interpreter I built in Python can run for millions of steps, and the visualizer written in Rust can handle trillions (see <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\">GitHub<\/a>). But even <strong>10 trillion steps<\/strong> isn\u2019t an atom in a drop of water in the ocean compared to the full runtime of the 6-state machine. And running it that far doesn\u2019t get us any closer to understanding <strong>why<\/strong> it runs so long.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Aside:<\/strong> Python and Rust \u201c<strong>interpreted\u201d <\/strong>the Turing machines up to some point\u200a\u2014\u200areading their transition tables and applying the rules step by step. You could also say they \u201c<strong>emulated\u201d <\/strong>them, in that they reproduced their behavior exactly. I avoid the word \u201c<strong>simulated\u201d<\/strong>: a simulated elephant isn\u2019t an elephant, but a simulated computer is a computer.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\"><strong>Returning to our central challenge:<\/strong> we want to understand what makes a short program run for a long time. Instead of analyzing these Turing machines, let\u2019s construct a Python program whose 10\u2191\u219115 runtime is <strong>clear by design<\/strong>.<\/p>\n<h2 class=\"wp-block-heading\">Rule Set 5: Infinite, Zero-Initialized Memory\u200a\u2014\u200aPlain Python (compute 10\u2191\u219115 without Turing machine emulation)<\/h2>\n<p class=\"wp-block-paragraph\">Our challenge is to write a small Python program that runs for at least 10\u2191\u219115 steps, using any amount of zero-initialized memory.<\/p>\n<p class=\"wp-block-paragraph\">To achieve this, we\u2019ll compute the value of 10\u2191\u219115 in a way that guarantees the program takes at least that many steps. The \u2191\u2191 operator is called <strong>tetration<\/strong>\u2014recall from Rule Set 4 that \u2191\u2191 stacks exponents: for example, 10\u2191\u21913 means 10^(10^10). It\u2019s an extremely fast-growing function. We will program it from the ground up.<\/p>\n<p class=\"wp-block-paragraph\">Rather than rely on built-in operators, we\u2019ll define tetration from first principles:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">\n<strong>Tetration<\/strong>, implemented by the function <code>tetrate<\/code>, as repeated <strong>exponentiation<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Exponentiation<\/strong>, via <code>exponentiate<\/code>, as repeated <strong>multiplication<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Multiplication<\/strong>, via <code>multiply<\/code>, as repeated <strong>addition<\/strong>\n<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Addition<\/strong>, via <code>add<\/code>, as repeated <strong>increment<\/strong>\n<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Each layer builds on the one below it, using only zero-initialized memory and in-place updates.<\/p>\n<p class=\"wp-block-paragraph\">We\u2019ll begin at the foundation\u200a\u2014\u200awith the simplest operation of all: increment.<\/p>\n<h3 class=\"wp-block-heading\">Increment<\/h3>\n<p class=\"wp-block-paragraph\">Here\u2019s our definition of increment and an example of its use:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">from gmpy2 import xmpz\n\ndef increment(acc_increment):\n  assert is_valid_accumulator(acc_increment), \"not a valid accumulator\"\n  acc_increment += 1\n\ndef is_valid_accumulator(acc):\n  return isinstance(acc, xmpz) and acc &gt;= 0  \n\nb = xmpz(4)\nprint(f\"++{b} = \", end=\"\")\nincrement(b)\nprint(b)\nassert b == 5<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Output:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">++4 = 5<\/code><\/pre>\n<p class=\"wp-block-paragraph\">We\u2019re using <code>xmpz<\/code>, a mutable arbitrary-precision integer type provided by the <code>gmpy2<\/code> library. It behaves like Python\u2019s built-in <code>int<\/code> in terms of numeric range\u2014limited only by memory\u2014but unlike <code>int<\/code>, it supports in-place updates.<\/p>\n<p class=\"wp-block-paragraph\">To stay true to the spirit of a Turing machine and to keep the logic minimal and observable, we restrict ourselves to just a few operations:<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">Creating an integer with value 0 (<code>xmpz(0)<\/code>)<\/li>\n<li class=\"wp-block-list-item\">In-place increment (<code>+= 1<\/code>) and decrement (<code>-= 1<\/code>)<\/li>\n<li class=\"wp-block-list-item\">Comparing with zero<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">All arithmetic is done in-place, with no copies and no temporary values. Each function in our computation chain modifies an accumulator directly. Most functions also take an input value <code>a<\/code>, but increment\u2014being the most basic\u2014does not. We use descriptive names like <code>increment_acc<\/code>, <code>add_acc<\/code>, and so on to make the operation clear and to support later functions where multiple accumulators will appear together.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Aside: <\/strong>Why not use Python\u2019s built-in <code>int<\/code> type? It supports arbitrary precision and can grow as large as your memory allows. But it\u2019s also <strong>immutable<\/strong>, meaning any update like <code>+= 1<\/code> creates a <strong>new<\/strong> integer object. Even if you think you\u2019re modifying a large number in place, Python is actually copying all of its internal memory\u2014no matter how big it is.<br \/><em>For example:<\/em><\/p>\n<\/blockquote>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">x = 10**100\ny = x\nx += 1\nassert x == 10**100 + 1 and y == 10**100<\/code><\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Even though <code>x<\/code> and <code>y<\/code> start out identical, <code>x += 1<\/code> creates a new object\u2014leaving <code>y<\/code> unchanged. This behavior is fine for small numbers, but it violates our rules about memory use and in-place updates. That\u2019s why we use <code>gmpy2.xmpz<\/code>, a <strong>mutable<\/strong> arbitrary-precision integer that truly supports efficient, in-place changes.<\/p>\n<\/blockquote>\n<h3 class=\"wp-block-heading\">Addition<\/h3>\n<p class=\"wp-block-paragraph\">With increment defined, we next define addition as repeated incrementing.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">def add(a, add_acc):\n\u00a0 assert is_valid_other(a), \"not a valid other\"\n\u00a0 assert is_valid_accumulator(add_acc), \"not a valid accumulator\"\n\u00a0 for _ in range(a):\n\u00a0 \u00a0 \u00a0 add_acc += 1\n\ndef is_valid_other(a):\n\u00a0 return isinstance(a, int) and a &gt;= 0 \u00a0 \u00a0 \u00a0\n\na = 2\nb = xmpz(4)\nprint(f\"Before: id(b) = {id(b)}\")\nprint(f\"{a} + {b} = \", end=\"\")\nadd(a, b)\nprint(b)\nprint(f\"After:\u00a0 id(b) = {id(b)}\")\u00a0 # \u2190 compare object IDs\nassert b == 6<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Output:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">Before: id(b) = 2082778466064\n2 + 4 = 6\nAfter:\u00a0 id(b) = 2082778466064<\/code><\/pre>\n<p class=\"wp-block-paragraph\">The function adds <code>a<\/code> to <code>add_acc<\/code> by incrementing <code>add_acc<\/code> one step at a time, <code>a<\/code> times. The before and after ids are the same, showing that <strong>no new object was created\u2014<code>add_acc<\/code> was truly updated in place<\/strong>.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Aside:<\/strong> You might wonder why <code>add<\/code> doesn\u2019t just call our <code>increment<\/code> function. We could write it that way\u2014but we\u2019re deliberately inlining each level by hand. This keeps all loops visible, makes control flow explicit, and helps us reason precisely about how much work each function performs.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">Even though <code>gmpy2.xmpz<\/code> supports direct addition, we don\u2019t use it. We\u2019re working at the most primitive level possible\u2014incrementing by 1\u2014to keep the logic simple, intentionally slow, and to make the amount of work explicit.<\/p>\n<p class=\"wp-block-paragraph\">As with <code>increment_acc<\/code>, we update <code>add_acc<\/code> in place, with no copying or temporary values. The only operation we use is <code>+= 1<\/code>, repeated <code>a<\/code> times.<\/p>\n<p class=\"wp-block-paragraph\">Next, we define <strong>multiplication<\/strong>.<\/p>\n<h3 class=\"wp-block-heading\">Multiplication<\/h3>\n<p class=\"wp-block-paragraph\">With addition in place, we can now define multiplication as repeated addition. Here\u2019s the function and example usage. Unlike <code>add<\/code> and <code>increment<\/code>, this one builds up a new <code>xmpz<\/code> value from zero and returns it.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">def multiply(a, multiply_acc):\n\u00a0 assert is_valid_other(a), \"not a valid other\"\n\u00a0 assert is_valid_accumulator(multiply_acc), \"not a valid accumulator\"\n\n\u00a0 add_acc = xmpz(0)\n\u00a0 for _ in count_down(multiply_acc):\n\u00a0 \u00a0 \u00a0 for _ in range(a):\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 add_acc += 1\n\u00a0 return add_acc\n\ndef count_down(acc):\n\u00a0 assert is_valid_accumulator(acc), \"not a valid accumulator\"\n\u00a0 while acc &gt; 0:\n\u00a0 \u00a0 \u00a0 acc -= 1\n\u00a0 \u00a0 \u00a0 yield\n\na = 2\nb = xmpz(4)\nprint(f\"{a} * {b} = \", end=\"\")\nc = multiply(a, b)\nprint(c)\nassert c == 8\nassert b == 0<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Output:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">2 * 4 = 8<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This multiplies <code>a<\/code> by the value of <code>multiply_acc<\/code> by adding <code>a<\/code> to <code>add_acc<\/code> once for every time <code>multiply_acc<\/code> can be decremented. The result is returned and then assigned to <code>c<\/code>. The original <code>multiply_acc<\/code> is decremented to zero and consumed in the process.<\/p>\n<p class=\"wp-block-paragraph\">You might wonder what this line does:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">for _ in count_down(multiply_acc):<\/code><\/pre>\n<p class=\"wp-block-paragraph\">While <code>xmpz<\/code> technically works with <code>range()<\/code>, doing so converts it to a standard Python <code>int<\/code>, which is immutable. That triggers a full copy of its internal memory\u2014an expensive operation for large values. Worse, each decrement step would involve allocating a new integer and copying all previous bits, so what should be a linear loop ends up doing <strong>quadratic total work<\/strong>. Our custom <code>count_down()<\/code> avoids all that by decrementing in place, yielding control without copying, and maintaining predictable memory use.<\/p>\n<p class=\"wp-block-paragraph\">We\u2019ve built multiplication from repeated addition. Now it\u2019s time to go a layer further: <strong>exponentiation<\/strong>.<\/p>\n<h3 class=\"wp-block-heading\">Exponentiation<\/h3>\n<p class=\"wp-block-paragraph\">We define exponentiation as repeated multiplication. As before, we perform all work using only incrementing, decrementing, and in-place memory. As with multiply, the final result is returned while the input accumulator is consumed.<\/p>\n<p class=\"wp-block-paragraph\">Here\u2019s the function and example usage:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">def exponentiate(a, exponentiate_acc):\n  assert is_valid_other(a), \"not a valid other\"\n  assert is_valid_accumulator(exponentiate_acc), \"not a valid accumulator\"\n  assert a &gt; 0 or exponentiate_acc != 0, \"0^0 is undefined\"\n\n  multiply_acc = xmpz(0)\n  multiply_acc += 1\n  for _ in count_down(exponentiate_acc):\n      add_acc = xmpz(0)\n      for _ in count_down(multiply_acc):\n          for _ in range(a):\n              add_acc += 1\n      multiply_acc = add_acc\n  return multiply_acc\n\n\na = 2\nb = xmpz(4)\nprint(f\"{a}^{b} = \", end=\"\")\nc = exponentiate(a, b)\nprint(c)\nassert c == 16\nassert b == 0<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Output:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">2^4 = 16<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This raises <code>a<\/code> to the power of <code>exponentiate_acc<\/code>, using only incrementing, decrementing, and loop control. We initialize <code>multiply_acc<\/code> to 1 with a single increment\u2014because repeatedly multiplying from zero would get us nowhere. Then, for each time <code>exponentiate_acc<\/code> can be decremented, we multiply the current result (<code>multiply_acc<\/code>) by <code>a<\/code>. As with the earlier layers, we inline the multiply logic directly instead of calling the multiply function\u2014so the control flow and step count stay fully visible.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Aside: <\/strong>And how many times is <code>+= 1<\/code> called? Obviously at least 2\u2074 times\u2014because our result is 2\u2074, and we reach it by incrementing from zero. More precisely, the number of increments is:<\/p>\n<p class=\"wp-block-paragraph\">\u2022 1 increment\u200a\u2014\u200ainitializing <code>multiply_acc<\/code> to one<\/p>\n<p class=\"wp-block-paragraph\">Then we loop four times, and in each loop, we multiply the current value of <code>multiply_acc<\/code> by <code>a = 2<\/code>, using repeated addition:<em><br \/><\/em><br \/>\u2022 2 increments\u200a\u2014\u200afor <code>multiply_acc = 1<\/code>, add 2 once<br \/>\u2022 4 increments\u200a\u2014\u200afor <code>multiply_acc = 2<\/code>, add 2 twice<br \/>\u2022 8 increments\u200a\u2014\u200afor <code>multiply_acc = 4<\/code>, add 2 four times<br \/>\u2022 16 increments\u200a\u2014\u200afor <code>multiply_acc = 8<\/code>, add 2 eight times<em><br \/><\/em><br \/>That\u2019s a total of 1 + 2 + 4 + 8 + 16 = 31 increments, which is 2\u2075-1. In general, the number of calls to increment will be exponential, but the number is not the same exponential that we are computing<em>.<\/em><\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">With exponentiation defined, we\u2019re ready for the top of our tower: <strong>tetration.<\/strong><\/p>\n<h3 class=\"wp-block-heading\">Tetration<\/h3>\n<p class=\"wp-block-paragraph\">Here\u2019s the function and example usage:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">def tetrate(a, tetrate_acc):\n\u00a0 assert is_valid_other(a), \"not a valid other\"\n\u00a0 assert is_valid_accumulator(tetrate_acc), \"not a valid accumulator\"\n\u00a0 assert a &gt; 0, \"we don't define 0\u2191\u2191b\"\n\n\u00a0 exponentiate_acc = xmpz(0)\n\u00a0 exponentiate_acc += 1\n\u00a0 for _ in count_down(tetrate_acc):\n\u00a0 \u00a0 \u00a0 multiply_acc = xmpz(0)\n\u00a0 \u00a0 \u00a0 multiply_acc += 1\n\u00a0 \u00a0 \u00a0 for _ in count_down(exponentiate_acc):\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 add_acc = xmpz(0)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 for _ in count_down(multiply_acc):\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 for _ in range(a):\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 add_acc += 1\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 multiply_acc = add_acc\n\u00a0 \u00a0 \u00a0 exponentiate_acc = multiply_acc\n\u00a0 return exponentiate_acc\n\n\na = 2\nb = xmpz(3)\nprint(f\"{a}\u2191\u2191{b} = \", end=\"\")\nc = tetrate(a, b)\nprint(c)\nassert c == 16\u00a0 # 2^(2^2)\nassert b == 0 \u00a0 # Confirm tetrate_acc is consumed<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Output:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">2\u2191\u21913 = 16<\/code><\/pre>\n<p class=\"wp-block-paragraph\">This computes <code>a \u2191\u2191 tetrate_acc<\/code>, meaning it exponentiates <code>a<\/code> by itself repeatedly, <code>tetrate_acc<\/code> times.<\/p>\n<p class=\"wp-block-paragraph\">For each decrement of <code>tetrate_acc<\/code>, we exponentiate the current value. We in-line the entire exponentiate and multiply logic again, all the way down to repeated increments.<\/p>\n<p class=\"wp-block-paragraph\">As expected, this computes 2^(2^2) = 16. With a Google sign-in, you can run this yourself via a <a href=\"https:\/\/colab.research.google.com\/github\/CarlKCarlK\/busy_beaver_blaze\/blob\/main\/notebooks\/tetration.ipynb\">Python notebook on Google Colab<\/a>. Alternatively, you can <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\/blob\/main\/notebooks\/tetration.ipynb\">copy the notebook from GitHub<\/a> and then run it on your own computer.<\/p>\n<p class=\"wp-block-paragraph\">We can also run tetrate on 10\u2191\u219115. It will start running, but it won\u2019t stop during our lifetimes\u200a\u2014\u200aor even the lifetime of the universe:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">a = 10\nb = xmpz(15)\nprint(f\"{a}\u2191\u2191{b} = \", end=\"\")\nc = tetrate(a, b)\nprint(c)<\/code><\/pre>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dotted\">\n<p class=\"wp-block-paragraph\">Let\u2019s compare this <code>tetrate<\/code> function to what we found in the previous Rule Sets.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Rule Set 1: Anything Goes\u200a\u2014\u200aInfinite Loop<\/strong><\/p>\n<p class=\"wp-block-paragraph\">Recall our first function:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">while True:\n  pass<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Unlike this infinite loop, our <code>tetrate<\/code> function eventually halts\u200a\u2014\u200athough not anytime soon.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Rule Set 2: Must Halt, Finite Memory\u200a\u2014\u200aNested, Fixed-Range Loops<\/strong><\/p>\n<p class=\"wp-block-paragraph\">Recall our second function:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">for a in range(10**100):\n  for b in range(10**100):\n      if b % 10_000_000 == 0:\n          print(f\"{a:,}, {b:,}\")<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Both this function and our <code>tetrate<\/code> function contain a fixed number of nested loops. But <code>tetrate<\/code> differs in an important way: the number of loop iterations grows with the input value. In this function, in contrast, each loop runs from 0 to 10\u00b9\u2070\u2070-1\u2014a hardcoded bound. In contrast, <code>tetrate<\/code>\u2019s loop bounds are dynamic\u200a\u2014\u200athey grow explosively with each layer of computation.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Rule Sets 3 &amp; 4: Infinite, Zero-Initialized Memory\u200a\u2014\u200a5- and 6-State Turing Machines<\/strong><\/p>\n<p class=\"wp-block-paragraph\">Compared to the Turing machines, our <code>tetrate<\/code> function has a clear advantage: we can directly see that it will call <code>+= 1<\/code> more than 10\u2191\u219115 times. Even better, we can also see\u200a\u2014\u200aby construction\u200a\u2014\u200athat it halts.<\/p>\n<p class=\"wp-block-paragraph\">What the Turing machines offer instead is a simpler, more universal model of computation\u200a\u2014\u200aand perhaps a more principled definition of what counts as a \u201csmall program.\u201d<\/p>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\">So, there you have it\u200a\u2014\u200aa journey through writing absurdly slow programs. Along the way, we explored the outer edges of computation, memory, and performance, using everything from deeply nested loops to Turing machines to a hand-inlined tetration function.<\/p>\n<h4 class=\"wp-block-heading\"><strong>Here\u2019s what surprised me:<\/strong><\/h4>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">\n<strong>Nested loops are enough.<\/strong><strong><br \/><\/strong> If you just want a short program that halts after outliving the universe, two nested loops with 144 bytes of memory will do the job. I hadn\u2019t realized it was that simple.<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Turing machines escalate fast.<\/strong><strong><br \/><\/strong>The jump from 5 to 6 states unleashes a dramatic leap in complexity and runtime. Also, the importance of starting with <em>zero-initialized<\/em> memory is obvious in retrospect\u200a\u2014\u200abut it wasn\u2019t something I\u2019d considered before.<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Python\u2019s <code>int<\/code> type can kill performance<br \/><\/strong> Yes, Python integers are arbitrary precision, which is great. But they\u2019re also <strong>immutable<\/strong>. That means every time you do something like <code>x += 1<\/code>, Python silently allocates a brand-new integer object\u2014copying all the memory of <code>x<\/code>, no matter how big it is. It feels in-place, but it\u2019s not. This behavior turns efficient-looking code into a performance trap when working with large values. To get around this, we use the <a href=\"https:\/\/pypi.org\/project\/gmpy2\/\"><code>gmpy2.xmpz<\/code><\/a> type\u2014a <strong>mutable<\/strong>, arbitrary-precision integer that allows true in-place updates.<\/li>\n<li class=\"wp-block-list-item\">\n<strong>There\u2019s something beyond exponentiation\u200a\u2014\u200aand it\u2019s called tetration.<\/strong><strong><br \/><\/strong> I didn\u2019t know this. I wasn\u2019t familiar with the \u2191\u2191 notation or the idea that exponentiation could itself be iterated to form something even faster-growing. It was surprising to learn how compactly it can express numbers that are otherwise unthinkably large.<br \/>And because I know you\u2019re asking\u200a\u2014\u200ayes, there\u2019s something beyond <strong>tetration<\/strong> too. It\u2019s called <strong>pentation<\/strong>, then <strong>hexation<\/strong>, and so on. These are part of a whole hierarchy known as <strong>hyperoperations<\/strong>. There\u2019s even a metageneralization: systems like the <strong>Ackermann function<\/strong> and <strong>fast-growing hierarchies<\/strong> capture entire families of these functions and more.<\/li>\n<li class=\"wp-block-list-item\">\n<strong>Writing Tetration with Explicit Loops Was Eye-Opening<\/strong><strong><br \/><\/strong> I already knew that exponentiation is repeated multiplication, and so on. I also knew this could be written recursively. What I hadn\u2019t seen was how cleanly it could be written as nested loops, without copying values and with strict in-place updates.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Thank you for joining me on this journey. I hope you now have a clearer understanding of how small Python programs can run for an astonishingly long time\u200a\u2014\u200aand what that reveals about computation, memory, and minimal systems. We\u2019ve seen programs that halt only after the universe dies, and others that run even longer.<\/p>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">All code from this article is available in an open-source <a href=\"https:\/\/github.com\/CarlKCarlK\/busy_beaver_blaze\/\">GitHub repository<\/a>.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><em>Please <\/em><a href=\"https:\/\/towardsdatascience.com\/author\/carlmkadie\/\"><em>follow Carl on Towards Data Science<\/em><\/a><em> and on <\/em><a href=\"https:\/\/bsky.app\/profile\/carlkadie.bsky.social\">@carlkadie.bsky.social<\/a><em>. I write on scientific programming in Python and Rust, machine learning, and statistics. I tend to write about one article per month.<\/em><\/p>\n<p>The post <a href=\"https:\/\/towardsdatascience.com\/how-to-optimize-your-python-program-for-slowness\/\">How to Optimize your Python Program for Slowness<\/a> appeared first on <a href=\"https:\/\/towardsdatascience.com\/\">Towards Data Science<\/a>.<\/p>\n<\/div>\n<p> \t<BR><br \/>\n <BR><\/BR><br \/>\n    Carl Kadie<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n<a href=\"https:\/\/towardsdatascience.com\/how-to-optimize-your-python-program-for-slowness\/\">Go to original source<\/a><br \/>\n \t<BR><br \/>\n <BR><\/BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to Optimize your Python Program for Slowness Also available: A Rust version of this article. Everyone talks about making Python programs faster [1, 2, 3], but what if we pursue the opposite goal? Let\u2019s explore how to make them slower\u200a\u2014\u200aabsurdly slower. Along the way, we\u2019ll examine the nature of computation, the role of memory, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,782,67,229,160,157,302],"tags":[731,2304,1833],"class_list":["post-2937","post","type-post","status-publish","format-standard","hentry","category-aimldsaimlds","category-computer-science","category-deep-dives","category-math","category-programming","category-python","category-software-engineering","tag-memory","tag-program","tag-rule"],"_links":{"self":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/2937"}],"collection":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/comments?post=2937"}],"version-history":[{"count":0,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/2937\/revisions"}],"wp:attachment":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/media?parent=2937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/categories?post=2937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/tags?post=2937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}