So, welcome back everyone. So, we have our next keynote talk by Victor Srinath. So, Victor is a Python developer for nine years and he is currently working at Red Hat. Victor has been contributing to open source software since 2002 and was nominated for Google Open Source Fear Bonus. One of his greatest projects named OpenStack was nominated for the Infinite Rebase Shared in April 2016. Victor is also the author of Piper, Paul Handler, and Ray Smollett's module. What do you Victor? The stage is yours now. So, hi everybody. My name is Victor Stiner. I'm working for Red Hat and I'm here to talk about the Python performance, the past, present, and future. I'm going to shut down the video because I have some upload issues of Python performance. There are multiple implementation of the Python language. There is C Python, which is the most famous because it was the first. And it is also the reference implementation nowadays. This one was created by Guido van Rosso. It was created 30 years ago. After this one, Jim Eginen created a G Python, later renamed just Jyton. This one is written in the Java language and C Python is written in C. After this one, Stackless Python was created by Christian Tissmer for a different purpose. The idea is to run different coatings in not in parallel but to... It's a concurrent programming. It's very similar to AsyncIO but using a different implementation. There is also Arun Python, created also by Jim Eginen. And this one is written in C-sharp using the Microsoft CLR. So, first target in Windows. And more recently, there is a new implementation called MicroPython by Damien George. And this one is targeting embedded devices with very low disk space and very low memory, which means less than 1 megabyte of memory. This project is very popular and I think it was the one running in the Lightning talk just before. So, there are different projects to optimize Python since the creation of C Python. The first one was created by Armin Rigo and it's called Psyco. The idea was to annotate one specific function and to optimize it when you executed multiple times. So, after a specific number of executions, the function is optimized by a JIT compiler. But Armin understood that this design is not efficient enough to make a Python application like two times faster. So, he created a new project called PyPy and this one is very different because it's a new implementation. There was a project started by two employees of Google called Unladen Swallow. The goal of the project was to make Python applications running four or five times faster. And they decided to use LLVM. Another project started by one or two employees of Dropbox and is called Bystone. And there is also a project started by two employees of Microsoft called Pigeon. So, you can see that there was many attempts to optimize Python. And I would like to notice that many of these projects except PyPy have an end date. And the end date means that the project development has stopped for some reason. And we will see why they stopped. So, there are two main approaches to optimize Python. The first one is to take the existing C Python for the project and attempt to implement your optimization. And the other approach is to write a new implementation from scratch. So, for the first approach, for King C Python, there are Unladen Swallow, Pystone and Pygion which took this approach. But one of the drawbacks is that the performance will be limited by the old C Python design. And again, C Python was created 30 years ago. For example, there is a specific memory allocator. There is a specific way to store object memory, the C structures. There is reference counting to manage object lifetime, which means a specific garbage collector, a specific way to detect when the object should be described. And one infamous limitation of C Python is also the global interpreter lock known as GIL. And because of the GIL, C Python cannot run more than one thread at the same time. The seventh approach to optimize Python is to write a new implementation from scratch. And, for example, there are PyPy, Jyton and IronByton which took this approach. And the great thing with this approach is that, for example, Jyton and IronByton have no GIL at all, which means that you can really run many threads in parallel. And these threads are running on multiple CPUs at the same time. It's not concurrent programming, but really parallelism. Another nice thing is that you can use a very different way to implement Python. For example, PyPy uses an efficient tracing garbage collector. It doesn't use reference counting. And the nice thing with tracing garbage collector is that the object can move in memory, so you can shrink the memory to reduce the memory footprints when you deallocate many objects. And also that reference counting as a drawback is that when you run two Python threads in parallel or even more, the reference counting can become a bottleneck because two different threads are accessing the same memory. And each time that you have a race connection, you have to protect the memory by atomic operation or locks. So the reference counting is not efficient for parallelism. But this approach as a main drawback is that C Python is very famous for C extensions, like a numpy, for example. And these implementations written from scratch have no support of the extension or limited support. And even if they support the extension, usually it's slower than C Python because the C API is not native, but they have to emulate the C API. For example, for the case of PyPy, there is a module called a Cpy extension which creates a C Python PyObject on the band. And this object has to be synchronized with PyPy objects. For example, imagine that you have a list which is using a very efficient storage for PyPy. It is efficient for the JIT compiler. It is efficient to reduce the memory footprint. But the first time that you use a C API on this list, PyPy has to convert the whole list to C Python PyObject, which is using more memory and they are less efficient for the PyPy JIT compiler. And the conversion from PyPy to C Python layouts requires to copy memory but also to convert the values, so it's not efficient. Another issue with the other implementation of Python is that when you have a different implementation, you are in competition with C Python. C Python project has around 30 active core developers to maintain it. And a bunch of core developers are even paid to do that, which means that they are working for companies who allow them to spend, for example, one day per week to maintain Python. In my case, I'm paid by Red Hat to maintain Python upstream but also downstream on Federa on Rare. And the new features coming in Python 3.9 or Python 3.8, etc., that you can see in the what's new documents of what's new in Python 3.9, for example, there is a long list of new features and all of these features are first implemented in C Python, which means that PyPy, for example, has to reimplement all these features but with a smaller team. So what you can see is that PyPy is always a little bit late in terms of Python version and Python features compared to C Python. I think that today they are supporting Python 3.6 and there is a beta version of PyPy supporting Python 3.7. And on the other hand, C Python is going to be released in version 3.9 in a few days, like next Monday, I hope. So the question is now, why would users prefer an outdated and incompatible implementation of Python and who is going to sponsor the development of different implementation of Python? In the case of the Nladen Swallow project created nine years ago by Google employees, the nice thing is that they wrote a report explaining why they stopped the development of the project. And I identified three main reasons. The first one is that most Python code running at Google isn't performance critical, which means that the performance critical code was written in a different language and Python is not really the bottleneck. So there is a little benefit to make Python really faster. The deployment of Python and Nladen Swallow was too difficult. Being a replacement was not enough to make Python more popular at Google. And our potential customers eventually found other ways of solving their performance problems. And this is something that we see often in Python, is that Python is not the most efficient programming language, but there are many ways to work around this limitation. For the N, Python itself, the Python interpreter, like a C Python, is not the first target when you would like to optimize something. In the case of Python, the project created by Dropbox three years ago, there was also a report explaining why the development has stopped. And I identified two main reasons. The first one is that Dropbox has increasingly been writing its performance-sensitive code in other languages, such as Go. And the other reason is that we spend much more time than we expected on compatibility. This is also an issue that I am seeing often on the other implementation of Python, is that there are many ideas to optimize Python, to make it more efficient. But when you optimize something, it's not uncommon that you change the behavior in a subtle way. And the issue is that a large project like Django are really based on the assumption that Python behaves exactly as a C Python. So when you optimize something, you have to really behave exactly as a C Python. And this is something that the PyPy developer, they paid a lot of attention to really mimic the exact behavior of C Python, and they spend significant time to really be exactly compatible with C Python. So the summary of the past section is that C Python remains the reference implementation, but it shows its age. So there are multiple optimization projects, but almost all of them failed. And the remaining one PyPy, it's a drop-in replacement of C Python, and it's around four times faster. But it's not widely adopted yet. The question is why? So let's move on to the present section, the present of Python performance. So to optimize your code, the first thing to consider is that you have to identify the bottleneck of your application. And let's say that you identify your bottleneck. And the question is that how can you optimize this bottleneck? How can you make your code running faster? The first thing that you have to do is to just try PyPy, because PyPy just works. PyPy is a drop-in replacement for C Python. It's around four times faster than C Python in average. But I would like to add that the exact speedup really depends on your workload. So it depends on which code is running, how your code is designed. But the great thing is that PyPy is fully compatible with C Python. And what I heard from PyPy is that sometimes there is a small part of your application which is running slower than on C Python. And in this case, you can ask PyPy developers for help and they can explain you how to make your code more efficient on PyPy. But there are some issues with PyPy. The main one is that the support of C extension using the C Py extension model is almost as efficient as on C Python, but sometimes it's slower. The great news is that two years ago, they organized a sprint and they managed to heavily optimize the code. But again, it's still slower than C Python. And I would like to discuss the C API later to explain this issue. Another issue with PyPy is that because of the JIT compiler, the memory footprint of your application is larger when you use PyPy than when you use C Python. It can be an issue if you would like to spawn many processes on your server and your server has a limited amount of memory. And the last issue which I would say is a minor issue is that when you use PyPy, the startup time, the time just to start your application is usually longer because, again, the JIT compiler, if your application is running for hours or for days, you will not notice and it's just fine. But there are many usage of Python and some people are using Python for command line programs which are running for a few seconds. And in this case, the startup time can be a bottleneck. Another common way to optimize Python is that once you identify your bottleneck of your application, it's common that you only identify a few files or a few classes or functions. And you can start with specific functions and try to revise them in the C language or REST by writing a C extension or REST extension. And by doing that, you can write way more efficient code because in C, you can make more assumptions and you can use more efficient way to implement the same feature. And today, REST is becoming more and more popular and there are two ways to write REST extension. The first one is REST C Python. The other one is PyO3. I never tried this one, so I cannot say which one is the best. So just try out and make your own opinion on that. The next property of REST is that the REST compiler provides a guarantee that if you write properly your code using the REST memory model, the compiler can tell you in advance that your program will not have memory errors like buffer overflows. There are many ways to ensure that there is no race condition and this is really a great video of the REST language, but you need REST C Python or PyO3 for the glue between Python and REST. And for example, the Mercurial Projects, which is a source tracking NCM source control management similar such as Git but written in Python. For the Mercurial Projects, there are some functions which are using heavily the CPU, which are CPU bound. And in that case, it's very interesting to rewrite some part of REST. So there is an ongoing effort to rewrite the performance bottleneck of Mercurial in REST and so far the project is quite successful. So let me come back to the infamous global interpreter lock called the GIL. So in C Python, there is a lock which prevents you to run many threads in parallel, but it depends on your workload. In the case of mathematical functions, I would say in general a pure Python code which is described as a CPU bound. CPU bound means that the performance of your application is not limited by the input on output, the IO, but it is only limited by the speed of your CPU. So for a CPU bound workload, C Python is not efficient because you can only run a single thread at the same time. Even if your machine has three CPUs and you wrote your code using threads to run them in parallel, in practice using C Python, there is no parallelism, there is only concurrency. It's one thread after the other. So if you imagine a machine with three threads and three CPUs, here the efficiency is only one third. But the GIL is not a bottleneck for any workloads. If your application has threads and the threads are more IO bound, for example, one thread is reading a file, another thread is computing the SHA-1 checksum of the file contents, and a third thread is compressing this data using bzip2. If you have this kind of workload, you are not limited by the CPU, it's more limited by... In this case, you can release a GIL, and if you release a GIL, you can really have a parallelism and execute all threads in parallel. So if you imagine a machine with three threads and three CPUs, in that case, you have an efficiency of 100%. If your workload is really a CPU bound, there is one simple solution, which is called the multiprocessing module. If you use the multiprocessing module, you can have one thread per process and run many, many processes in parallel. And thanks to that, the operating system is able to execute the process in parallel and really use the power of all your CPUs of your machine. And the multiprocessing module is making that easy, so you don't have to manage the process yourself. The multiprocessing takes care of spawning the process, sending the data, retrieving the results, and stops the process when the workload is done. Thanks to the multiprocessing module, for a CPU bound workload, you can have again an efficiency of 100%. And this module is already existing in Biden for many years, so it's ready to use solution. So the multiprocessing module, it works around the yield limitation, the global interpreter lock. And the great news is that in Python 3.8, released one year and a half, released one year ago, sorry, you can get shared memory. And shared memory means that you don't have to serialize and copy the memory between the different workers. You can just use a chunk of memory which is accessible by all the workers. And thanks to that, you don't have to copy anymore. So it's way more efficient for very large amount of memory, like very large matrix in NumPy. And the second great news is that again in Python 3.8, there is a new particle protocol, the particle version 5. Again, this new version avoids copying very large objects. 5.74. The idea is that you can decide how you send a large amount of memory. And for example, you can delegate as a serialization using shared memory, so you don't have to copy the memory. You can write your own code to decide how to send the data. Previously, I said that one way to optimize a function is to rewrite it in the C language, the C extension. But if you use the C API of C Python, it can be very boring because you have to manage the memory yourself. You have to manage the reference counting. You have to manage the exception. Check for failures of each function. And the C language is less... It takes more lines to do the same thing than in Python. So the idea for this item project is that you write code such as Python. So the syntax of your code is very similar to Python. But you add a few annotations. And thanks to this annotation, the site is able to produce way more efficient code than you would get if you write it in Python or in C yourself. And the great thing with Cytan compared to using the Eclise C API is that if you use Cytan, you can easily support multiple Python versions and also get a better support of PyPy or other Python implementation using the same code base. So you don't have to manage the very subtle differences of the C API between the different Python versions. And the other nice property of Cytan is that you don't have to handle the reference counting manually. Cytan is doing that for you. And also the only exceptions are many things which are very boring. So you don't have to write all the exposure plate code. And the last great property of Cytan is that the Cytan optimizer emits efficient code using Cytan internals for you. So you don't have to know how Cytan is implemented. Cytan does that for you. And thanks to the knowledge of the Cytan internals, Cytan, sorry, is able to produce way more efficient code than the code that you would write yourself. Another project to optimize your code is Numba. Numba is different, is more specialized to scientific applications. For example, code using a Numba. So Numba is a JIT compiler translating a subset of Python and NumPy into fast code. And there are many ways to execute the same code faster. There are different implementation. There is simplified threading which is a way to run threads. But these threads are releasing the gil. So if you recall what I explained previously, if you release gil, you are able to use all the CPUs of your machine and you get a parallelism. Numba is also able to emit single instruction, multiple data vectorization, which is a way to run the same code way more efficient. There are many CPU extensions for that, like AVX, AVX 5.1.2. And the last way to optimize code is the famous GPU acceleration like NVIDIA CUDA. But Numba also supports AMD HockM, which is another way to run your code on the GPU. And all the solutions are way more efficient than the code that you would run usually using a numpy, for example. And the very nice thing with Numba is that you don't have to rewrite all your code from scratch. What you have to do is just to annotate a few functions using a little decorator and that's it. To come back to see Python, there is a website called speed.python.org which is tracking the performance of Python over time. The really nice tab is a timeline where you can see the performance over the last five years. Here is an example of Telco benchmark which is a benchmark on the Desimine module. It's a benchmark to compute the sums of numbers for a common benchmark called Telco. And here you can see that all the five years as the performance of Python is becoming way better, which is a great thing that we don't regress but become more efficient. When I spend a lot of time to make this benchmark more stable because previously we got a lot of noise in the results, a lot of spike faster or slower. So what I did is to write a new module called PyPath, which is a way to run the benchmark differently to get more stable results and more reproducible results. And after that, I modified the Cpython benchmark suite called PyPath month. I modified it to use PyPath. Thanks to that, now the results are more and more stable, so it's easier to use a result to take a decision. In summary, for the present section, PyPath doesn't require any code change, so you have to test PyPath on your code and see that it's faster. If you identify the bottleneck of your application, you can attempt to rewrite a few specific functions as the C or REST extensions. Multiprocessing scales, it's really enable parallelism on many CPUs, and it is really easy to use. To write the extension, use Sight and Please, don't use the C API directly. And Numba makes Numba faster. Okay, we saw a lot of existing solutions to make your Python code faster, and I would like to show you a few experimental projects to attempt to optimize Python even more. I spend a lot of time to analyze why C Python is slow, and why the optimization project failed in the past. And I think that I identify one big reason, which is the C API of C Biden. The C API evolved organically, which means that internal functions are exposed by mistake. And this C API was first written to be consumed by C Biden itself. There was no overall design. The design is just expose everything and don't think about if it's a good idea or not. And 30 years ago, it was just simple and good enough. But what we get today is that the C API expose way too many implementation details and because of that, it's way more difficult to optimize Python. So in Python 3.8, I did many changes in the C API and I'm still working on that in Python 3.9 and in the next Python 3.10. And one big change of Python 3.8 is that instead of having a single API at the same place where you get private function, internal function and public function, I split this API in three parts. So the main include directory is a public stable C API. The C Python directory is a C API specific to C Biden. And the internal sub directory is an internal C API. So this API should only be used by C Biden itself. But I decided to expose it anyway for very specific use case such as a debugger or a profiler which has to inspect the object of Python without executing Python because a debugger should not modify the state of an application but only inspect what is a current state. And many private functions are fixed on underscore pi and the pi interpreter state structure have been moved to the internal C API in Python 3.8. Another interesting thing in Python is a stable ABI. The idea of the stable ABI is to support multiple Python version. For example, Python 3.8 3.9 and later Python 3.10. Using a single binary. So the idea is that you build your six tension once and you can use the same binary on multiple Python version. So for example, for a Linux vendor instead of having one package for Python 3.8, one package for Python 3.10 which becomes annoying when you would like to support it. Thanks to the stable ABI you are able to ship a single package a single binary and support a large number of Python version. So what changed in Python 3.8 is that the debug build is no ABI compatible with the release build which is really interesting for debugging purpose because when you get a crash in Python it's very likely that the crash doesn't come from Python code but more from the C extension and if you use the debug build you get way more sanity check and running at runtime to detect bugs and thanks to this check it's more likely that you get more information about the crash and thanks to this change you can use your existing C extension compiled in release mode using a Python compiled in debug build because previously in Python 3.7 you had to recompile all your C extension and that can be very tricky if you get many requirements many dependency like header files or compiler or something else that will build your C extension So to come back to the C API and why it is an issue to expose the implementation detail you would like to take the example of a specialized list in C Python a list is basically an array of pointers an array of pointers to py object which is a real content of an object but in PyPy there is a strategy to get specialized lists so if you consider a list which only contains integers PyPy is able to store this list as an array of integers so there is no indirection from the list to an object which is stored somewhere else in memory and you get directly the value of the item directly in the list and thanks to that you get lower memory footprints but you also get better performance because there is no indirection so the CPU doesn't have to fetch the numbers from somewhere else and the question is now can this optimization be implemented in C Python and can we modify the pylist object structure of C Python and the answer in short is no we cannot the first problem is that to access an item of the list there is a macro in the C API called pylist get item and this macro access directly into the list access directly the obi.item member of the pylist object and this item is a pointer to a py object and the C extensions must not access the pylist object members directly because if you do that you get you expose the direct memory layout and you cannot change the layout because if your machine code is accessing directly the memory to a specific offset if you change the memory layout instead of getting a py object star you get a number or something else and your problem is going to just crash so the pylist get item macro could be modified to convert the number of a specialized list to a py object star but there is a second issue with that and the second issue is called the borrowed references if we come back to the macro pylist get item let's imagine that you implemented the specialized list so in C Python a list is made only on numbers and when you get an item of the list the macro magically creates an object on demand but if you do that you get borrowed references which means that the list doesn't know when the caller is still using the object returned by the macro or when the object can be destroyed this is a borrowed references and you must not use the py decref to decrement the reference counter of the object you must not use it on the object that means that if the macro creates an object the list doesn't know when this temporary object can be destroyed and this is an issue for the correctness but also an issue for the performance because you can keep an object longer than what it should be we don't know when the object can be destroyed and this is an issue and sadly many C functions of the C API are returning borrowed references so we can do a better C API and for that one thing to do is to make the structure opaque which means to prevent the extension to access the actually members of the structure and instead of accessing directly into the structure we have to use a function call because the function call is hiding how the members are stored in memory so for example when you create an object in Python using py long from long you get an object but currently you can directly access the obi underscore type a member of the object to get this type and this is an issue we should not be able to do that we should hide the way to retrieve the type of an object using for example py underscore type a macro the second thing to do is to remove functions borrowed references or functions which steal references which is another issue similar to borrowed references and as I said we have to replace macros with a function calls so when you build your C extension the C extension will only call functions on this function will do the work for you to hide the implementation details but by doing that there is one issue that people don't like is breaking the backward compatibility because any C API change can break an unknown number of projects and maybe not all C API design issues can be fixed we can try to fix a bunch of C extension for example the most popular C extension on PyPI but fixing all C extension on PyPI can take a lot of time or even infinite time so maybe there is another way to fix this issue there is another project called HPI which is a new C API the idea of HPI is to design the C API correct since they want correct means that you hide the implementation details and you design the C API such as it can run in the most efficient way on C Python but especially in PyPI because PyPI has a different constraint as a different memory layout and HPI if you use HPI the code is running way more efficient on PyPI the base design of HPI is that there is no more PyObject star so there is no more pointer to PyObjects this API is using PyHoundl and Houndl is an opaque integer something that you cannot inspect and you can see that such as a Unix file descriptor when you open a file on Unix you get a number and you call function you pass this number to function and the number is a private reference to an internal object in the Linux kernel or you can also see that as Windows Houndl on Windows you have also when you open a file when you create a lock when you do many operations you get an opaque Houndl and you only call functions on this Houndl and the base operation open you get a new Houndl duplicate to copy on Houndl and close the Houndl and thanks to this new API based on PyHoundl you get better performances and the nice thing is that you can you don't have to rewrite C-Python from scratch you can just take the existing C-API and implement H-Py on top of the existing C-API of C-Python and this has been done and there is a second implementation written especially for PyPy which is making an assumption on PyPI internals and thanks to that you can get more efficient code if you write it using H-Py rather than the performance that you would get if you use the existing C-API of C-Python and I think it was last year they managed to rewrite G-Zone parser using H-Py and the modified G-Zone parser is running something like four times faster on PyPy than the implementation using the existing C-API and four times faster is really interesting so it's a proof that the design makes sense and that there is another way to solve this issue and the great thing is that if your C-extension is written using C-Python there is a way to not have to modify your code because we can modify C-Python using the new PyUnder for you so using the H-Py projects so there is an ongoing work to modify C-Python to generate directly the H-Py code so you don't have to modify your C-extension so again please don't use the C-API directly just use C-Python ok we'd like to come back to an issue of C-Python which is reference counting the problem of the reference counting is that it is tied to the global interpreter lock and to to remove the global interpreter lock the reference counting becomes an issue so there is a project called a Guild Actomy started by Larry Hastings which is trying to remove the Guild from C-Python the idea is to replace a unique Guild with one lock mutable object mutable means that you can modify an object in place like a list, a dictionary or a set object and for example one way to do that is to implement the reference counting using increment on decrement instructions CPU instruction Atomic means that if two threads are running the instruction in parallel the CPU ensures that the operation there is no race condition to implement the Guild Actomy Larry tried to to create a log of decrement operation and by doing that it's possible to run the code faster in multiple threads but the implementation is quite complicated and sadly on benchmark this implementation didn't scale well instead of running code faster than C-Python at the end it was running slower than C-Python which is the opposite of the goal of the overall project so I would say that the war issue with the Guild comes from the reference counting and the reference counting doesn't scale with a number of threads so what we should try to do in C-Python is to replace the reference counting using a tracing garbage collector because many modern language implementation use a tracing garbage collector like PyPy for example the idea is to be able to move objects in memory and to identify where the objects are stored in memory and thanks to that the code is able to run faster in parallel but for the existing C-API if we move to C-Python to a tracing garbage collector thanks to the C-API they will continue to use reference counting for the external codes which will hide how the objects are stored in private, in internals internally and to finish there is one cool project called sub-interpreters there is a PEP written by Eric Snow the PEP 554 in the Stornart library the idea is to replace a single global interpreter lock with one lock per interpreter which means that you can run multiple instances of Python in parallel and by doing that each interpreter gets a full speed of Python so it becomes possible to run to run separated interpreter at a full speed and really scale with the number of CPUs there is a work-in-progress refactoring work of C-Python but it's a long-term project because it takes a lot of time to modify all the existing code and to not break the background compatibility but I think it was in last May I proved that on a machine with four physical CPUs and with four cores it is able to run the code up to two times or maybe four times faster using a modified implementation of C-Python using sub-interpreters running in parallel means one sub-interpreter per CPUs so I had an experimental implementation of that and I proved that you get a similar speed or the same speed than multiprocessing but inside the same process and the nice thing is that having a single process it's more easy to manage because managing a bunch of process can cause other issues like larger memory footprints to show you that instead of having a single process and multiple threads limited to one CPU per thread so all threads of the same interpreter you have using sub-interpreters the idea is that each interpreter has its own threads and each interpreter is as a dedicated CPUs so again you get an efficiency of 100% 5 minutes left so the expectations of sub-interpreters is to get lower memory footprints because we should be able to share more memory we should get faster locks because the locks are inside the same process it's not a locks between two process but one of the limitations of sub-interpreters is that you cannot directly exchange a Python object between two interpreters you have to design your application directly to not share objects so the summary of the future of the Python performance is that the Q&C API has design issues there is a new PyUndle API a new API called HBuy using PyUndle which is a work in progress we should try to use a tracing garbage collector for C-Biden and there is an exciting project which is to run sub-interpreters inside the same process so to conclude there were many previous optimization attempts which failed but Cytan, multiprocessing, Numba also C and REST extensions are working well to make your code faster and HBuy, Tracing Gavage Collector and sub-interpreters are very promising projects to optimize Python so thank you all, I give you links to the different projects that I listed like PyPy my notes on how to make C-Biden faster my notes on the Python C API the speed project where we are tracking the performance of Python there is also a mailing list to discuss the optimization project speed at python.org and the last link is a link to the HBuy projects but I will not have enough time for questions so if you want you can ask me questions on Zulip Dostinez and thank you


Hello there, my beautiful, I almost fell there, okay. Hello there, my beautiful, lovely, talented, and delightful. I am unstable, all right, let's try that again. Hello there, my beautiful internet friends. Welcome back to my channel. Thank you so much for joining me here today on Footless Joe, where I am Joe, I am missing a foot. And I wanted to share a few major misconceptions that I had about being an amputee before I became one myself. There were a few things that I was really certain of and others that I didn't even think about before I had this amputation surgery that turned out to be very, very wrong. And I wanted to share those with you for a variety of reasons. It makes for a fun video. Also, I think it's good to get this information out for anyone who ever has to consider having any amputation or if you know someone who does. I thought for this video format, we would do something a little bit different. You see, I am home alone for the evening, which is great, it's lovely to have some alone time, but I need to make dinner and I'm usually making dinner for two people. And so, if I'm not making dinner for two people, I usually just grab a bowl of cereal because that's so much easier, but I wanted to actually eat something that was relatively healthy or fresh tonight. And so, as I go through some of the bad ideas I had about amputation, I thought I'd have you guys make dinner with me because it helps me feel less alone. Even though technically I am still alone in my house filming this video, but it feels better. So let's make some sour, creamy chicken formables. I think that's how you say that. All right, well, that's fun. Did you see that? What was that? What was on fire? And talk about some of the things that I was very wrong about. But before we do that, allow me to introduce you to our amazing sponsor. Well, thank you, Past Joe. I appreciate that segue. Feeling safe is something that's really important to human beings. We need to feel safe where we're living, where we're working, but something that not many of us consider is are we safe with what we're doing online?  That is where a VPN comes in. And if you are not worried about your internet safety, first of all, I think it is something that would be important to consider. But secondly, a VPN will also allow you access to all kinds of entertainment that you would not already be able to have. That's where Surfshark comes in. They are a VPN that allows unlimited devices, which is pretty fantastic. Other VPNs do not allow that. 24-7 support, an ad blocker, and more. A VPN, if you don't already know, is a virtual private network that allows you to safely and securely connect without sharing your data. If you're sitting in a coffee shop and you log into Facebook, do you really want the creeper over in the corner being able to grab your information because you're on the same network? No, you don't. Use a VPN. It's what I do. Or on the other hand, if you're interested in accessing content on, say, Netflix or Hulu that is not available in your country, you can use a VPN to change your country. And voila, you have access to more content than you ever could have dreamed. So if you are interested in your internet safety or interested in additional content, check out Surfshark. If you use the code PUTLISTSHOW at checkout, you will get over 80, that's right, 80. Try to sign it with my fingers, it didn't work. Over 80% off at checkout, which is a pretty fabulous deal and I really appreciate Surfshark for sponsoring this video. With that being said, let's dive back in to Joe from a few days ago in the kitchen. Will she make dinner that's edible? I don't know, we're gonna find out. All right, so as my rice cooks, let's talk about one of the first misconceptions I had about being an amputee. This is one thing that I was like really jazzed about. I was like, yeah, I'll finally get that right once I cut my leg off. And I have no idea how I didn't actually think this through a little further. The reason I had an amputation is because I had a fused ankle that had lots and lots of problems. I had had a ton of surgeries on it. It was in a lot of pain, there was nothing else they could do. And I couldn't walk right. Like my ankle was always out to the side, it was always turned out, I was always limping, like my alignment was all thrown off. And I thought if they cut it off, they can just align a leg that's perfectly right for my body and my body alignment will be better without my leg. That was by no means a deciding factor, but that was something when I was like, hey, this could really help some of the other chronic pain that I have. It might help the alignment in my neck and kind of the stress that I hold there if I'm better aligned throughout my whole body. In retrospect, I'm really unsure why I thought a piece of metal would be better aligned to my body than an ankle. This is an amazing contraption, absolutely fantastic engineering. However, it's very difficult to get even the height perfectly right for your hips. It's hard to get the right level of like pressure on the foot. It's a lot of trial and error trying to figure out how, you know, how stiff you want this part of the foot through adjusting screws and things like that. There definitely is not better alignment in my body after missing a leg. I would say it's probably a lot worse. I'm just more aware of it and I can take care of my body a little bit better. But I had this great idea in my head that replacing a human body part with a metal one would fix my alignment issues and I was incorrect. As we move on to chopping peppers, I do want to note that in no way do I regret my decision even with these things that I had misconceptions about. I kind of just looking back, some of them are just kind of funny to me. Like, did I really think that? Did I really not think of that? This was 100% the best and the right option for me. But it has definitely come with some surprises. You know it's getting serious when I pull my hair up. Let's chop some peppers. It may look like I know what I'm doing in the kitchen from this video, but I guarantee you, I do not. I'm always a little intimidated when I step in the kitchen to make anything other than macaroni and cheese or cereal. I'm very good at making cereal. If you need a cereal chef and by chef, I mean someone to like assemble the cereal. I'm your girl. Keep up with the small talk. First call with the breaks off. We don't need to see the far.  I know I'm an option. What are you doing? Trying to get some scraps. She's looking for some scraps too, aren't ya? Misconception number two, or rather just something I didn't really think about. The amount of maintenance and lifelong maintenance that it takes to be an amputee was kind of surprising to me. Ooh, that's the bell, meaning our race will be done here pretty shortly. And I was fully aware of the fact that I was gonna have to like find a prosthetist to make my prosthetic leg and then there'd be fitting appointments and things like that. But what I don't think I fully thought through is the fact that from now until the day that I die, if I live an average life, I should have another 50 years left. You know, fingers crossed, here's what I'm hoping. If I make it to like 70, that means I've got 50 years left. Nope, 40, 40, I'm bad at math. Also, that's a lot shorter than I was thinking. That means I've got 40 years left of adjusting screws and alignment and making sure that I have enough socks. All right, let's take this rice off. I always have this problem where I try not to overdo rice and so I always end up underdoing it. So fingers crossed, I did the right amount this time. I was very familiar with the fact that there would be maintenance but the amount of parts and pieces like having a sleeve that needed to be replaced every three to six months, having leg socks to add extra padding when you're walking, those tend to disappear and you gotta buy more of them. Things like refilling special silicon lotion bottles to make sure that rough spots or painful spots on my leg can move a little bit easier in the liner, things like that. I didn't think about the amount of maintenance and the fact that that will be from now until the day that I die. But two years in, realizing that I am always gonna have a relationship with a prosthetist, I don't just get my leg and then we're good, that parts and pieces will get holes unexpectedly and I've gotta replace them or order more or beg with insurance to get me a new one. It was like I said, something I was aware of but the reality of it is a lot more work and mental energy than I expected. Now, speaking of energy, let's talk about energy after I get the bell peppers into the pan. Oil, I had oil. Ha, the sun is setting and I'm getting this like blinding light because I can't actually close those blind. Hopefully that looks all right.  Here's a hoping the sizzling isn't too loud that you can't hear me talking. Thing number three that I got wrong was energy. The amount of energy that it takes to do everyday normal activities.  Ooh, okay. All right, well, that's fun. Did you guys see that? Did you see that? What was that? What was on fire? It's normal for things to be on fire when things are cooking but they were flames. Hi, Mikey. Did you come to make sure I was okay? Thank you. Anyways, like I was saying, I was aware of the fact that being an ATT, obviously you're gonna use a little bit more energy for things but I didn't realize how much I would physically feel that with daily activities. I figured, okay, if I'm going for like a 10 mile hike once I'm adjusted to my prosthetic leg and everything, maybe totally understand if I felt a lot more tired then. But it's not even that. It's not even like the exercise is a big thing so much. It's the little things like standing up at the end of a long day and making dinner in the kitchen on my prosthesis. My body is exhausted and I'm soaring weird places and I just wanna lay on a heating pad and go to sleep by six o'clock. Now thankfully, your body does start adjusting to the amount of energy that you need but it's always gonna take 10 to 20% more energy to exist as an ATT. I didn't really factor that into my calculations. I feel like the sizzling is very loud. By the way, I picked this up for like $5 a really long time ago. It's a lemon cistern and I'm very proud of myself for having an actual kitchen tool in the kitchen. I really don't cook that much. It's like the seventh time I've used this. I see you're a hot thing. I know I'm an option. It ain't gonna break my heart. That's too much water. It's burning. Yeah, we're doing great guys, we're doing great. I'm just saying. I think the sauce looks pretty delicious. It just looks like sour cream because it's mostly sour cream. Thing number four that I did not predict about being an amputee. The fact that complications and revisions and having to have more surgeries is actually pretty common. It's not something that's unusual. I had a good number of complications and setbacks, but the more amputees I've talked to, the more I realize that that's pretty normal. Rarely does anyone have a perfectly smooth journey from losing their leg to learning to walk again. I had my amputation October 11th, 2018. Then I had a bad fall in December, which led to a burst of forming, which is like an internal callus that doesn't go away and is pretty painful. Removing that didn't work. Turns out the bones never healed in my leg, so they had to cut more of my leg off a few months after that. And eventually I got to the place where I was able to walk really well. Now, but it took a long time. I had this timeline in my mind of like, I'm gonna have my amputation within eight weeks. I'll get my prosthetic leg. And within a few months after that, I'm gonna be hiking. When the reality was it was more like 18 months. And I think if I'd gone into it with a little bit more of an expectation of setbacks are really common. You never know how your body's gonna respond or react to something. And I think there's an art to learning to roll with the punches. So while what I experienced would have been challenging regardless, I wish I could go back and tell myself that like, hey, this process is gonna take longer than you think and that's okay. Number five, number of legs that are required for activities. Now what I mean by this, and I really hope you can hear me over the chicken sizzling this time, last time it was the bell peppers. You know, I had seen amputees walking around before, lurking in corners as I do now. And I never really thought about the fact that the legs that they were using to walk around a grocery store are not the same legs that amputees use to go for a hike or maybe go for a bike or go running, right? I'd seen amputees with running blades but that was about it. I need to remember to actually keep storing this as I'm talking. Otherwise, we're gonna have some burnt chicken. I remember at my first prosthetics appointment what my first prosthetist, who is not my current prosthetist, asked me was do you wanna be able to wear high heels or go for a hike? Like those were my two options for getting a leg.  Like if you need a different leg for high heels than you do for hiking, just get another one. But the problem is they're really, really expensive. Prosthetic legs range in pricing. The one that I have right now was about $18,000. Insurance helps pay for that, but it does not pay all of it. And insurance only covers one leg every three years, meaning the leg I have on right now is the only one insurance is gonna pay for for another year and a half. So if I wanna run, I've gotta shell out the money for it or find a grant. Now, thankfully, I have a friend who helped me out and gave me a running blade, which was absolutely amazing. If I wanted to get on a bike, I would need to use a different socket. You know, socket is the part that actually attaches to my body because my walking leg socket wouldn't let me bend my knee far enough to like have that full rotation on the bike. This smells so good. I cooked the rice too long this time. That's okay, very dry and chunky. By the way, if you feel like critiquing any of my cooking etiquette, please feel free. I am by no means a chef, as I've said at least one other time in this video. And I'm still learning. I've been trying to learn to cook a little bit more, do a little bit more in the kitchen. It actually is kind of relaxing at the end of the day to like make your own food, make good food, make maybe good for you food. I mean, this isn't like the healthiest meal ever, but it's definitely healthier than the cereal I was going to have. So to all my cooking and chef friends out there, let me know what I could do better to make this whole thing easier. Timing is definitely something that I need to work on because the rice was kind of cold by the time the chicken was done, but I'm a beginner, I'm still learning. I usually try to clean up as I go, but tonight I've got a live stream right after I film this. So I'm gonna say the dishes for later. Or for Brian, we'll see what happens. And we have success. My friends, success. We're in the process of rearranging our house. So there's sort of things everywhere. This was really good. So as I was saying, as the chicken was coming off our stove, definitely the number of legs for different activities was surprising to me. If you watch one of my recent videos with Annika, I'll link it down below. She talks about having seven or eight different feet, different legs. Now, can you get by with just one? Yes, absolutely. But if you wanna have some fun, if you wanna participate in more things, sometimes you need additional legs and sometimes those are accessible and sometimes they aren't. Thank you for making dinner with me, guys. I legitimately feel less alone. I really appreciate you joining me.  So those are the top five things that come to mind when I think of kind of misconceptions or things I didn't think about or things I was just wrong about about amputee life. So the five things I talked about tonight are some like, you know, more challenging things. But the reality is that there have been so many amazing, incredible things that have come along with this journey to things I could never have predicted like you, like all of you watching this channel, like the opportunity to grow and the opportunity to challenge myself in new ways and meet such incredible people and have great conversations and learn more about myself. That's a gift that could never be replaced. I'm so grateful for that. And if I had any misconceptions that amazing things wouldn't come out of this as well, I was definitely incorrect there because I certainly have. I'd love to hear if you like this kind of video, if you like a, you know, dinner and chat sort of video. Let me know in the comment section down below. A huge thank you again to our sponsor. All their information is linked down below and thank you to my patrons for keeping this channel alive and thriving. I truly appreciate each and every one of you. I can never express my gratitude for the support you've given me. To you watching this video, the same thing holds true. I'm so grateful for you being here. Thank you for spending a few minutes out of your day here with me today, cooking some chicken shawarma bowls. I really hope I'm saying that right. You could be anywhere in the world doing anything and you chose to hang out with me for a few minutes and I really appreciate that. I love you guys, I'm thinking about you and we will see you in the next video. Now to finish dinner. Bye guys.


Our first caller is Jessica from Louisiana. Hey Jessica, how can we help you? Hey guys, thanks for having me. So my question is more about calorie intake and muscle definition. I have been consistently weight training for about a year before that was more so on and off and more focused on endurance. But for the past year, it's just been weight training focused, little to no cardio. But I feel like I'm not getting the muscle definition that I want mainly my glutes or side glutes and on midsection. And I was wondering this was because I'm not eating enough but also because my concern is my midsection I was wondering if I should be strict on my diet. I mean, it's already kind of hard for me to eat more but I was wondering if I need to guess count calories or attract foods and limit fats if my goal is to build more ab muscle or show my abs more. And then I also was wondering if I should be focusing my exercises more on like glute exercises like adding more glute exercises, more ab exercises and how would I do that without having to stay at the gym for two hours every time I'm going over there for weight training? Yeah, no, great question. All right, so the couple of things you said that are kind of hints to me that in terms of the advice I'm going to give you. So number one, if you want to develop those muscles more you might need to do a little bit more volume or maybe change up the exercises for them. But one thing you said that was really interesting you said, I don't know if I can eat anymore.  So I did, at one point I was tracking macros I was also downloaded an app, a fitness call to track what I eat. And there were times where I would, I think I stayed between 1500, 1400, maybe 1600 on some days, but it was a struggle and that was more so because I was trying to increase protein and I've also always been, I guess, trying to stay away from carbs, but that was not helping me when I was weight training, especially on the strength when I was training more strength because I was lacking energy. So somebody told me I may have to do more carbs, but I'm just, I guess I'm afraid to increase because I always think that I want to focus on my abs. So I feel like I may gain fat instead of strength, so. Jessica, I know it's very rude to ask this, but for context, can you tell me how much you weigh? 122 pounds. Okay. How tall are you? 5'3". Oh, okay. So it's a pretty appropriate body weight. If you're doing resistance training. And it says right there, are you squatting 145 for four reps too? I see that on your notes. Yes, yes. So it sounds like to me that you're pretty healthy, pretty strong, you're a pretty good body weight for your size, but you want more definition, but there's nothing wrong with that. There's nothing wrong with wanting to go to the next level and lean out or see more muscle definition, but this is in my opinion, this is where tracking is so important. You're not somebody who's just trying to be strong, fit and healthy. You want another level to your aesthetics and you want to see definition. And this is where it does get a little more nuanced with exactly where you're at calories and macros. And so I would challenge you to get back onto tracking and to see where you're at. And we would, because here's the thing, you have abs, you have a side butt, it's there. If you want to see more definition, it will be leaning out and dropping body fat percentage. And in order to do that, because you're already in a pretty good place, sounds like you're kind of intuitively eating and maintaining a pretty good place. But if you want to go to the next level, it might take the next level of dedication, which may mean for you tracking, not so much you need to do more work as far as in the gym, but maybe you just need to do more work around tracking and paying attention to what you're in taking. Yeah, I mean, you could literally figure out your average calories and just cut them down a few hundred. And you'll probably get what you want, especially now that we know your weight and your strength, because like Adam said, you're in a really good place to do that. It sounds like a really good place to cut a little bit and then to see that come purely from body fat. Okay, okay, well thanks. Yeah, no problem. And good job, by the way.  I mean, you were doing a lot of endurance stuff before, but for the last year you've been weight training. Your strength is good. Body weight for your height is phenomenal. So great job, you're in a great position. Thank you guys, thank you. I'm glad I found y'all. Awesome, no problem. You've been helping me a lot. Awesome, thanks for listening. All right, thank you. You know, it's tough with these because when you're talking to a potential client in real life, you could see what they look like. Well, yeah, that's why I have to ask that. You know, I know it's rude to ask somebody to weigh their weight in context. But I mean, I could kind of tell what I saw. We can see on her notes, right? So she didn't say it, but we can see the notes. So it pops up on the TV screen and it says that she's squatting 145 pounds. I'm like, she's squatting 145 pounds. She sounds like she's eating relatively good. She's full, you know what I'm saying? So I'm like, what's her weight at? She says her weight.  So she's in pretty, it sounds like she's in pretty good shape, but she wants the next level. And it's like, okay, well, this is where. This is where you gotta get the specific. Yeah, this is where tracking is so important. Like, you know, I can maintain even myself, even with all of our fitness knowledge and experience, I can maintain relatively healthy and fit and strong. But if I want abs or I want to look a certain way, even I go back to tracking, I go back to tracking so I can be very precise about it because when you're trying to get down to that body fat percentage to expose your abs and show separation, it takes more intensity. Yeah, yeah, a lot more focus on that. Yeah, especially when you're a female, like getting down to get like visible abs as a female is actually more challenging than it is for a man. They hold more body fat. So, you know, it would be hard for a woman to get to that kind of leanness without tracking and doing it properly. Unless genetically you were already a very lean person. Right, right, right.