Full podcast episode: ua-cam.com/video/-DVyjdw4t9I/v-deo.html Lex Fridman podcast channel: ua-cam.com/users/lexfridman Guest bio: Guido van Rossum is the creator of Python programming language.
Yet Guido makes a mistake. To know if a number is a prime, one divides by each previous prime known: 2, 3, 5... not 4. Still one of the the guys that shaped the world as we know.
It was a great privilege to listen to Guido van Rossum, thank you sir for your gift to the world, your invention has created opportunities for me and millions of others.
This interview reminds me of the issues I had in the 1980's speeding up the looping of my employer's implementation of the byte-coded language "Business BASIC"...FOR I / NEXT I loops defaulted to the case where the internal floating point format was used versus the 99.99%+ case of the 32-bit integer type...I still remember those Asm/C coding days fondly...Visiting in Chicago last summer, walking past a sideway cafe, one patron asked me to explain my custom T-shirt: "Only malloc() can set you free()".
the trick about operator optimization sounds almost exactly like branch prediction. If you have a branch in your code and one path is consistently chosen, modern CPUs will just execute that path and then check afterwards if it was the right thing to do. It's really the exact same idea
Modern algorithms using SIMD try to remove branching entirely, aka “branch free”. It can often be faster to do _slightly more work_ (trade latency) for higher throughput.
That's why I like languages which do static type inference. It prevents run time bugs and errors and it runs faster while the programmer does not have to write type annotations. The compiler will tell you there is something wrong with the types when the original programmer is still around to understand what the problem is. Then he can fix it before it goes into production.
I used to love the speed of writing in dynamically typed languages. As I've gotten more experienced, I've learned to love the safety that comes with strong typing an inference. It takes longer to write the code, but less time to *maintain* the code.
The thing I really, really love about Python, being someone who very much prefers static typing and pre-allocating variables to keep memory structures simple & performance deterministic, is that Python doesn't hide pointers but in fact makes it part of the language, making C and Python kind of a match made in heaven when you want the best of a dynamic scripting language and the low-level performance of C or assembler. Now that's a fucking long sentence.
3:39 "Well, actually 10 is divisible by 2" - I LOLd when I realized that Guido actually lives what he did with the original python: why memorize whether 10 is a prime, when you can quickly compute it in you head.
I am learning coding in python at 51 just for fun with no prior coding experience nor use for it. As I suffer from ADHD, my ability to get distracted and waste time never ceases to amaze me. So it's been 4weeks and I am still at list comprehensions. I am not sure why I thought I would understand and relate to this interview :) But I still appreciate it. Now let me go and find something to waste time on.
Sounds to me like optional typing could help boost performance here… if the user specified a type, the interpreter skips the initial „not-keeping“ and assumes it is going to get that type every time.
when is the type checking enforced? you'd need an explicit compilation step, but at that point you may as well be using a compiled language altogether. What they could do is just provide official support for compiling python and allow the programmer to choose between using the interpreter or compiling it. Kind of like what Java already does.
@@ianrust3785 there already is a compilation step though, it’s being compiled to bytecode, the type checking could be enforced then… but maybe i’m understanding wrong…
@@curls6778 That's happening at runtime, while the code is being interpreted, on certain critical pieces of code. To do static type checking the whole code needs to be compiled prior to runtime, where you can output an error message & signal the programmer to fix the bug. Something they could also do is use a linter & type hints to do partial type checking... this can be done in python already using some 3rd party tools. If these tools were integrated with the interpreter the optimizer could make more liberal assumptions about type-hinted variables.
23:00 The idea is also used in modern CPUs. It will go down a jump-if branch it has gone many times before while doing the actual test in parallel, and when the test is done, if the assumption was wrong, it will backtrack.
The problem with python is that the efficient type-static code needs to be written in C and put into libraries like numpy, then glued together using a 'glue' which is slow and type unstable. This means you are limited to using libraries in order to have an actual performant code, unless you want to get down to compiled code (which is not what most of the python user-base want or is capable of doing). The solution to this is allowing optional typing in the glue (python), so that you can actively choose to make bad/slow (bust easy) code or good/fast (but harder) code. This is what languages like Julia have solved from the get-go, where both the high-performance kernel libraries and the dynamically-typed high-level scripts can be coded in the same programming language.
Python is fast and performant for the vast majority of use-cases, and Julia has bugs and has a poor language ecosystem. It takes more than types to make a language, though I will admit for large projects they are sorely needed (but these are 1% of use-cases). You don't need libraries to make python good. Some people choose numpy inappropriately, where even standard lists would be faster (quickly appending values, using disparate objects in your list, etc.). Most things can be done in pure python. Ive even seen entire game engines written in pure python built by solo developers, with really good performance rivalling even that of industrial engines like Unity. Python has a reputation for bad performance that just isn't true, when you look at it realistically and not theoretically. It aint going nowhere.
@@dreambuffer As a mathematician doing research in computational methods for HPC, I can tell you you are absolutely wrong about the performance of Python versus typed languages. That said, I agree it is good enough for most use cases.
I don't think Python will ever manage to fix a problem so fundamental. It's like asking for natively supported green threads in C - never going to happen. I'm glad languages like Julia exist and I hope they get the mindshare they deserve.
I figured out by myself that root thing when I was in the first semester of CS and was trying different methods to generate prime numbers. It's what taught me programming logic the most. I used to write down the logic and the code on a notebook and think wow this is complicated, now It's pretty easy to think about those rules I figured out. I just realized I've come a long way.
simple is a complex subject. I remember once a gold mining company hired me to optimize a fortran code. the code was easy to understand but it was 1100 lines long, but besides taking several weeks to process large volumes of data, in some of these cases it crashed. so I decided to take a different approach and instead of using arrays I used Lists. The resulting prodigy had 117 lines and was 5 times faster, but if you don't know pointers in fortran it is much more difficult to understand the code.
Ok, I'm really curious how you did that. Arrays in Fortran *should* be super optimised by the compiler; pointers not at all because of lack of data contiguity and jumps. Was it because your data was better modelled by recursive structures?
Lex, please invite some of the Julia lang folk for a chat, like Alan Edelman, Chris Rackauckas, Jeff Bezanson, Stefan Karpinski, etc. I'm sure they'll have a lot of interesting things to say about elegant and performant language design.
I have always taken the approach to code that first, you make it work. Then, you make it user friendly. Then, you make it fast. That's just the way to go. I've always been a bit surprised that compilers and interpreters weren't a bit smarter, in the sense that they don't keep track of the constraints that the code has established... like if in a function a variable is set to an integer, same happens to another, and then later they get added together without any code that could change their type intervening, it can 'know' that they must be integers. It should be possible to track this sort of thing all the way from input (whether from keyboard, network traffic, file, whatever) to use, so that the compiler could figure out what is possible and what is not possible once it hits a certain segment of the code. Instructions don't just return results, they establish constraints and that should change how further code is treated, I would think. Python is my favorite programming language. I've been coding since I was 12, and I am 44 now. I've done a litany of many different languages, from x86 assembly to C/C++ to Java, C#, LISP, I even really liked Eiffel for awhile. It is a pleasant surprise that Python is so good for beginner programmers, but as an experienced programmer, I absolutely love it because it makes it easy for me to code as I think, and the guardrails that might be useful for a learning programmer, stuff like strict static type checking and such, are simply not mistakes I make any longer, so those guardrails only get in the way. It does shift some burden onto the interpreter, for sure, but I'm simply not going to send in an argument that doesn't have some necessary method I call on it, so I really don't need all the cruft of having to define its type just so the compiler can do some compile-time checking to warn me about it. I am hoping that one of the parts of the 3.11 speedups focuses on the startup of the interpreter. I know that usually dominates the execution time of many short scripts, with 50% or more of the entire execution time of the script being taken up just getting the interpreter started.
Same approach. I think it applies to anything science, trial and error. By making it works, you understand the matter and will look for a better way by learning from the actual working solution. It has to work first since a proof of a 'solvable' solution to a particular problem.
Always make it right first and in many cases you never should optimize it. About the tracking in the compiler, there are languages which do this. Functional languages which do type inference for example.
@@AlJay0032 I agree. On modern hardware, if your code is slow but you're not dealing with some problem which simply requires a truly profound amount of computation (like on the order of trillions of operations or unavoidable triply-nested loops), it almost always means you chose the wrong algorithm, the wrong data structures, or both. And yeah, type inference is great... but I have yet to see a compiler that takes advantage of the constraints beyond that. It might use a faster floating point low level operation than an integer one on the CPU... but I've never seen one that would optimize away a conditional like "i < 20" based upon there simply being no code paths through the program which could even possibly result in a value of i greater than 19. I don't mean that 3 lines prior i is set to 15 or something, I mean i is composed of digits read from the keyboard and then manipulated, passed through various functions, eventually ending up being passed in and it could be seen by someone who understands the whole process that even if the maximum possible value was input, no matter what the end result would always be less than 20 by mathematical necessity. Most optimizing compilers don't do whole-program dataflow analysis like this. I've just always been surprised when I write some code and I'm like "I know these conditions are going to be met" but then the compiler doesn't seem to 'know' the same limitations. I always assumed compilers were just 'smarter' than humans when it came to code, but hand-tooling low level things still comes in handy, albeit quite rarely nowadays.
What is mindboggling, there could easily be both static typing and dynamic typing in Python. In simultaneusly... That would be a step closer to the world where you have one language that can be runtime interpreted (fast prototype) and after with little to no changes to compiled to machine code (fast performance). Type annotation is already nescessary, if you want to do anything complicated with python. Your problem: It is classical hindsight problem. You has the knowledge of program, but computer is stupid as ever. Knowledge mean calculation and that takes resources. Current interpreter only need to know local namespace and not to know whole program (and without annotation, it is very hard to do with computer). Cost of knowledge of every connection in program can easily be higher than some little mistakes in runtime. Generality always makes everything slower, and when you implement own knowledge you always make everything faster (generality: error check everything in production cycle. Knowledge: Check integrity only once in factory's terminal, material does not mutate in production.) But that said, I would love program that analyses every connection in complicated programs and make dynamic visual graph about it. That essentially is same problem.
It's correct, though. They say dot, rather than point, so it isn't a decimal point. You don't have the property that 3.1 and 3.10 are the same thing, or that 3.11 is somewhere between them. Theorem and figure numbers work the same way. I tend to just not pronounce the punctuation at all, but if I did I definitely would never say 'point'.
He gets a bit lost in narrow details, and forgets to talk about the bigger picture, or gets so abstract it remains too vague. I mean most of what he said so far until 13:38 can really be said about programming languages in general. Ok, regarding the optimization, the short summary is he does some kind of caching/memoization and code specialization/instantiation, such that generic functions are implemented in more type specific ways, which allows to remove things a generic function would have to do. 19:30
@@oksatoki But pandas is a framework that utilizes native implementation heavily, as well as numpy. They are not vanilla python. They were always faster than vanilla python, and in fact they were as fast as other languages as you have stated. The problem is that python is not really that fast enough if you are using structres of python only. Like, python numpy arrays are waay more faster than python vanilla lists. And even python has some functions that are implemented in native langauge, which makes them a lot faster. For example, if you had a list of integers with the lenght of 5.000.000, calling the python function sum() will actually invoke the native implementation of the sum function which will perform way faster than just suımming the values in your code with a for loop. Even for loops will be faster than the while loops because their implementation differs in the interpreter level, which is of course impelented in a native langauge. I guess what I am trying to say is, python frameworks were never the problem. Python itself was the problem. A developer must know the tricks of using the built-in functions rather than implementing themselves, and that is not as easy as it sounds. Some of the functions can be really tricky to use for your data, and wting a function that iterates over each data in the list might be easier for some cases. If the extra performance is required, in that case the developer must use external frameworks like numpy or pandas, or use built-in funcionts and shape their code around that. Which in return may reduce the readibility and maintanability of that code. That is true for all languages, but that scenario is encountered more frequently with the case of Python.
I've read it a lot, on Python forums, and in YT comments so..... Of course, never in your life will Python itself actually be able to fast computationally. Python is as fast as Basic calling assembler routines, nothing else. As an aside, PureBasic built by a 1-2 man team results in a compiled .exe that is basically as fast as C, without having to call external libs. So I was wrong, Python itself is slower than Basic, and with external libs doing the heavy lifting, still nudged out by a Basic.
This whole clip is just a very roundabout explanation of how Python should just really finally have a static-type mode where I can FINALLY declare a function that really only can ever accept two integers and I really mean JUST TWO INTEGERS not any other type Python!! grrrrrr
I used to be a big fan of Python syntax. Still find it really expressive and, as dynamic typing language goes, it is probably the cleanest to work with. But I have come to see dynamic typing as a beginner trap. As Guido mentioned in this video, it is certainly handy to have the flexibility of bringing a variable into life without specifying its type. However, the drawbacks are that it is painful to work with on larger projects, especially with third party code as the compilers/linters provide very to no help as to what a valid argument for a given function call. Moreover, the fact that important performance tricks need to workaround this feature is also confirming that dynamic typing is objectively a bad idea on all fronts, except maybe for beginners or prototyping work... Very interesting talk however.
@@venkataramanapodugu6211 CPUs expect exact bits. Some high level languages hide that so you can do big number math without bothering with that, but that comes at the cost of speed. Unreal Engine 5 looks great but doesn't use Python for performance.
". As Guido mentioned in this video, it is certainly handy to have the flexibility of bringing a variable into life without specifying its type. " At the very least you should have to specify you're declaring a new variable though. How does turning typos from hard errors into silent logic bugs help anyone, especially beginners?
@@isodoubIet I think the biggest practical benefit for development an interpreted language, whether static or dynamically-typed is that of iteration speed during development/prototyping/learning because you don’t need to wait nearly as long for a build cycle. In that perspective, interpreted languages make for faster human iteration, and compiled languages make for faster computer iteration, and static typing is where both the compiler and human can more quickly settle on an optimal solution. Dynamic typing is most immediately helpful while the human is still pondering types, but once there’s been a clear decision, it ceases to have practical value to remain dynamic, at least at the level of simple operations of simple types, particularly scalars and built-in types like strings.
@@strictnonconformist7369 The "iteration speed" benefits drop off very early, around when the code is about a page long. After that the interpreted/dynamic nature slows you down because errors are only caught at runtime after a bunch of processing has happened.
@@AntoshaPushkin ..he seems like a mafia gangster from the 30s, who stepped into a time machine, that travelled to the future to interview the creator of Python.
Prime numbers are amazing. I have used them for a collision system before because you can uniquely identify objects using primes including if they overlap themselves. E.g. you can tell an ID is the same just by checking modulo like 503 and 1006 are the same ID.
Do you know if this technique has any established research term, etc.? I created same idea when I was pondering insanity of multi-event sport scoring. I named it as prime-substitution, because you can map ordinal-Naturals with ordinal-Primes and then multiplicate scores. Original scoring is saved as a number. It has limits in space-complecxity as growth of Prime-factorial is insane. And in the end there is still combinatory- problem, where certain combination of event and contender counts still has change of tie. But can be usefull for something else, like unique arithmetic ID:s, but everything prime related are calculation heavy, and most times not usefull.
i find the rienman zeta function as one of the most mind blowing examples of beauty in the world. so aesthetically pleasing. And this beauty is so intrinsically related to the art of building efficient algorithms. Introspecting the unlimited set of general cases of a problem into a single, finite expression is pure gold.
Ok math nerd. Calm down. I could say the same thing about bernoulli numbers or the gamma function. They are all the same thing really. You should refrase as: "numbers in general are mind blowing...."
As Python developer, I would like to have static typed Python. Even for begginers I would be helpfull - it's good to know from beggining to be aware of types on variables and function parametrs etc ....
Yep, Pyhon is a neat language but the lack of static typing (or a static-typing-mode) is extremely painful to work with, even disregarding the obvious performance impact
yeah, i'm a beginner/ not even a proper programmer, and even I prefer static typing. I've done some hello world-esque stuff in c/c++ and some unity c# scripting and fell in love with static typing there.
"As a biker, i would like to have 4 wheels bikes." That's basically what you're saying. The difference between a bike and a car is the number of wheels. If you want 4 wheels choose a car, don't use a bike. The difference between a dynamic language and the others, is when types are computed. If you want static types, use a compiled language, don't use a dynamic language like python. I find it so weird when people say "I'm a python developer" while having no idea what Python is...
As I have gotten more and more invested into c++ template programming, this discussion reminds me more of a discussion of generic programming in c++, and less of a Python one. I also feel like c++ and python have become closer to each other(in my own view), with "auto", "constexpr", and "std::format". The compiler at compile time in c++ also feels more like the interpreter at run time in python, minus the GIL of course. That is just my opinion and perhaps more of a rambling
Regardless of all the “looks like dynamic” for “auto”, “constexpr” and “std::format” they’re still statically-determined at compile time, while Python is always at runtime, with an observed repetition slightly optimized for, compared to default dynamic assumptions of the language specification itself. The 3 C++ details you mention all make it easier for the human to reason about the code with less cognitive load, whereas the mentioned implementation details of the Python is all about making it easier for the byte-code interpreter to “reason” about the code with less “cognitive” load.
@@strictnonconformist7369 Yep I agree. I just think its sort of interesting that parts of this vlog just sort of felt like it could have come out of a cppcon talk. I was looking at the matplotlib cpp source the other day and all the templating just sort of reminded me of how "x=0" in python feels like "auto x=0;" in cpp from a coders point of view. Like you pointed out, it has nothing to do with what is actually going on when it is being used, it just sort of "feels" more similar now compared with old 90s cpp era code writing. Things like smart pointers, auto type deduction, lambdas, all just feel sort of "Pythonesc"(totally not a word) but maybe that has to do more with me learning Python first before I got seriously into cpp. Who knows?
@@scienceandmathHandle if you want a truly disorienting language for syntax and keywords, go with Swift: it’s sort of like English in that it assimilates words/concepts from many other languages Borg-like while having some things all its own. It has type inference which in theory makes it less explicit for types for writing the code as someone reading the code, but that’s also been known in past versions (I need to check in the current version) to be less than ideal in implementation, resulting in absurdly long compilation/build times, assuming it doesn’t tell you the expression is too complex, if you depend too much on type inference. Swift is a Swiss Army Knife of languages in that, like C++, it’s truly multi-paradigm, and for so many things, there’s not a single “only use this” way of doing things. For supposedly being an easier language to learn, it has a rather large amount of syntactic and semantic complexity. There are parts I love about it (type inference is both a blessing and a curse) where it has grabbed things from elsewhere. It’s even more flexible than C++ in some ways in that due to needing backwards-compatible with Objective-C, it’s simultaneously able to support SmallTalk message type OO that’s not so strictly-typed, while also being able to work with more C++-like strictly-typed objects that help for performance. Like Objective-C evolved to have before the transition to Swift, it uses Automatic Reference Counting, with a few more tweaks: it’s more like COM than the garbage collection of Python or other languages, and is much more deterministic. And yet, Swift, meant as a systems language, doesn’t exactly have a small runtime, so isn’t nearly as suited as C/C++ for embedded microcontroller software. I’d expect Python may be smaller.
@@strictnonconformist7369 Thanks for your feedback, and take a thumbs up on me! I would like to check out Swift sometime when I get the time. I hear its pretty cool. But unfortunately it is not what what we use at work. I wish I had the time to learn "GO" and "Rust" too! There is only so much time in the day though. But there is a general trend right now towards .NET at work that I may not be able to escape from. So I guess I will see what the future holds.
So with 100% code coverage, all types should be known and could be automatically added to the code to speed up first runs on other machines. from typing import Final can be used to create const vars for futher speedups. Or switch to Rust and only mark some things as mutable. V and Nim have simpler syntax, though, but even contracts like Ada/Spark and its mathematical correctness can be generated.
But python allows arrays of heterogeneous types, right? So adding two vectors doesn’t mean it is adding vectors of integers, as elements could be a combination, for example, of integers, BigInts, strings and even matrices. Just as an example. Inferring the types may seem trivial, but the way a language like python handles typing, it is not.
100% code coverage doesn't mean 100% branch coverage. Formal verification is close to impossible for python, because there might always be something that goes wrong. One solution could be to have everything bear-typed (assert the types at runtime), but it can be quite expensive.
Thinking about the add example from the perspective of what a CPU is capable of, most CPUs can do multiple math operations per cycle without SIMD instructions and many more per cycle with SIMD. What was described here for operators is maybe tens of cycles (or maybe over 100 cycles) for one math operation. The described operator process is several orders of magnitude slower than the theoretical maximum of the hardware. For python, assuming a JIT, why not approach the performance optimizations as how to get close to theoretical maximum capability of the CPU (for tight loops) versus tricks to do better but still orders of magnitude slower than CPU theoretical capability?
My understanding about the ethos of Python is historically do everything as simple as possible, but no simpler. This certainly has a performance cost. I won’t pretend to know the long-term Python implementation objectives, but a true JIT compiler definitely is not that philosophy. There are scenarios (hard real-time) where consistent known performance is more important than amortized better performance that has performance glitches. I was amused lately to learn there is “circuit Python” intended for embedded microcontrollers. A Python with a true JIT is something I’d never expect to fit in such a scenario. There are certainly great advantages to a language design/implementation that is sufficiently minimal yet complete that you maximize its reach as-is with one implementation regardless of actual machine platform. I’ve not checked if they’ve added a meaningfully-larger amount to it since I used it 10 years ago, but as an example, Lua has in the past been embeddable as a single 29kloc standard C source file. It’s beautifully-portable and embeddable, and more than fast enough for most scenarios, and doesn’t suffer from the GIL, making it easier to work with multiple threads (though the language doesn’t officially support them) by using multiple instances in the same process, as the host process can easily take care of synchronization.
Mike, I get your point. And I do not understand "as simple as possible, but no simpler". Isn’t "but no simpler" redundant? I don’t really see consistent performance for "hard real-time" programs as precluding the larger picture optimizations Mike alluded to. A much faster loop that does several integer optimizations will always perform that way, for integer data types. If the data types happen to be matrices or strings or something, the program will perform consistently, but slower for those types.
@@MrFrimko C# is not interpreted in the same way Python is, so it's not an apples-to-apples comparison. Also, simplicity often means the most straightforward implementation whereas the performant ones are often way more complicated. String searching and matching would be a good example. Matrix multiplication algorithms also fall into this category.
A thought I had is why not reapply the addition operator function when the type of the variable gets reassigned? In theory if the type never changes, there wouldn't be a need for all of this accounting. I'm sure there's a reason for this.
Yeah… Guido’s continuously pulling us back down to earth. He’s right that there will always be people doing unrealistic stuff to try and prove a point, even a redundant one. It’s like complaining about the top speed of a bus.
I was like, "Oh, cool! This would be a good talk to listen to while defining octonion addition and multiplication in Python." Imagine my reaction at 14:00
Lol. Just heard the comment “ better to assume the weather today is the same tomorrow as it is today, because that is better than staying with a random value” to which I say not in Scotland is not. 😂
I‘m a little confused. I thought the more compute intense a task is, the lower is the time portion taken by the interpreter. This would imply that low compute intense programs benefit more from 3.11. Is my assumption incorrect?
Not much. Unless types are enforced by the compiler itself, type annotations are really for high level readability and documentation. I like them, and I use them in python, but I dont rely on them that much. And I prefer static typing
Well, I don’t know. Having a lot of frustration with Python 3.11. Changes to Seaborn plots that no longer support positional x and y values requires a lot of working code changes. Pandas pd.read_hdf no longer works, no module named ‘tables’, pip install pytables. But that gives no matching distribution found for pytables, Can’t install torch or PyTorch, TensorFlow, etc, etc…
Python sucks because every single version is only properly compatible with itself, I don’t get how anyone can use it when everything breaks in the next MINOR version
@@Fantaztig Yeah, it is probably my biggest issue with actually running Python code done by others. The language devs (or publishers) should be more careful about how the versions handle or try to handle older code..
Yep, just add performance, static types, no GIL, proper threading, maybe LINQ, and soon, you'll have what C# had 15 years ago. Python is a great example of why popular is not good (and then there's JavaScript, lol)
I remember reading about tagged operations, i think it might have been called, 45 years ago (in Communications of the ACM? Perhaps 1977?). But implemented in the hardware, machine language. Exacly the same idea, but implemented in the machine architecture, instead of in software. I don't think any computer ever implemented it. But I thought it was a good idea!
So as I understand this as a very green Python dev.. the interpreter stops checkin both operands types after an arbitrary amount of runs. Meaning it assumes types after completing the operation without errors.
the whole interview is so amazing it really makes you wonder how the f***k we live in a society where Kanye West gets much more credit and attention than one of the guys that genuinly contributed to shape the world we live in.
This is how the history of mankind has always been. In the short term we remember the clowns (entertainers) but in the longterm remember the leaders and the scientific progress.
Python is viable for many of its modern uses because of performant C++ library implementations underneath it. Listening to this talk about complex type abstraction at the bytecode level you know that "fast" is a relative term here.
C isn't a low level language. Low level language are for example all the assembly High level language are for example all languages that are compiled into assembly. now if you want a general rule to understand how to identify low level vs high level and this was the consensus in every compiler book before the internet allowed for the distortion of terminology. there is something called "translation layers" all this translation layers exist both in hardware or software. If your language is meant for use by translation layer in software and requires a complicated syntax analysis then is high level. If your language is meant for a translation layer in software that requires a simple 1 to 1 translation like assembly or is meant for hardware interpretation then is low level even if the translation is complicated. In the past some mainframes had BASIC as their assembly. C is meant to be translated by a compiler (offline translator) offline translator means that the translation takes files and dumps files Bash is meant to translated by an interpreter (online translator) online translation takes single instructions or files and performs the actions immediately. Java/python/Ruby are hybrid of offline and online translation, Java is right in the middle because it has a compiler into bytecode and then you distribute the bytecode so the translation and execution are not on line. Ruby and Python translate into bytecode internally and keep that in memory and then execute the bytecode, so they are hybrids but are closer to online translators than the middle on/off line translation. Now, is possible to make an interpreter for all compiled languages like C, and run them but they are not going to have the same semantics.
Full podcast episode: ua-cam.com/video/-DVyjdw4t9I/v-deo.html
Lex Fridman podcast channel: ua-cam.com/users/lexfridman
Guest bio: Guido van Rossum is the creator of Python programming language.
Thanks, Lex.
Never in my life did I think I'd listen to a lecture on computation of prime numbers from Guido van Rossum.
@@ohio exactly. It's just lazy techbros who are blown away by this. Musk types.
@@edbee8508 Waaa
Life-changing experience bro
boasting about python 3.11 being the fastest yet is like boasting about being the top student in a special ed program
Yet Guido makes a mistake.
To know if a number is a prime, one divides by each previous prime known: 2, 3, 5... not 4.
Still one of the the guys that shaped the world as we know.
It was a great privilege to listen to Guido van Rossum, thank you sir for your gift to the world, your invention has created opportunities for me and millions of others.
This interview reminds me of the issues I had in the 1980's speeding up the looping of my employer's implementation of the byte-coded language "Business BASIC"...FOR I / NEXT I loops defaulted to the case where the internal floating point format was used versus the 99.99%+ case of the 32-bit integer type...I still remember those Asm/C coding days fondly...Visiting in Chicago last summer, walking past a sideway cafe, one patron asked me to explain my custom T-shirt: "Only malloc() can set you free()".
the trick about operator optimization sounds almost exactly like branch prediction. If you have a branch in your code and one path is consistently chosen, modern CPUs will just execute that path and then check afterwards if it was the right thing to do. It's really the exact same idea
Indeed I stumbled upon the same thought. It reminded me of when I learnt how assembly deals with jump operators. Same idea
Yes, but I think he is trying his best to make it simple to understand for people who haven't studied this deeply
Modern algorithms using SIMD try to remove branching entirely, aka “branch free”. It can often be faster to do _slightly more work_ (trade latency) for higher throughput.
branch prediction is mostly related to L2 cache prefetching instructions and data, but in this case nothing is getting prefetched..
Spectre has entered the chat 👻
This discussion did a really good job of speaking in a way that allows beginners to understand
That's why I like languages which do static type inference. It prevents run time bugs and errors and it runs faster while the programmer does not have to write type annotations. The compiler will tell you there is something wrong with the types when the original programmer is still around to understand what the problem is. Then he can fix it before it goes into production.
I used to love the speed of writing in dynamically typed languages. As I've gotten more experienced, I've learned to love the safety that comes with strong typing an inference. It takes longer to write the code, but less time to *maintain* the code.
I got to say python father is such a nice guy to explain so much detail to him (so patiently)
The thing I really, really love about Python, being someone who very much prefers static typing and pre-allocating variables to keep memory structures simple & performance deterministic, is that Python doesn't hide pointers but in fact makes it part of the language, making C and Python kind of a match made in heaven when you want the best of a dynamic scripting language and the low-level performance of C or assembler.
Now that's a fucking long sentence.
Bro wrote a paragraph
@@chickengamer14 Word
@@chickengamer14 hardly
It's not that long actually.
@@mAcCoLo666 That's what she said
3:39 "Well, actually 10 is divisible by 2" - I LOLd when I realized that Guido actually lives what he did with the original python: why memorize whether 10 is a prime, when you can quickly compute it in you head.
That's why I love Lex Clips, it's not always fluffy for the general public. Even as a professional one can learn something from the speakers.
10:56 That audible scoff during Guido's answer did not go unnoticed, Mr. Fridman.
Lol yes
I am learning coding in python at 51 just for fun with no prior coding experience nor use for it. As I suffer from ADHD, my ability to get distracted and waste time never ceases to amaze me. So it's been 4weeks and I am still at list comprehensions. I am not sure why I thought I would understand and relate to this interview :) But I still appreciate it. Now let me go and find something to waste time on.
My ADHD is out of control...I want to learn python but I also want to watch these birds chirp.......
Sounds to me like optional typing could help boost performance here… if the user specified a type, the interpreter skips the initial „not-keeping“ and assumes it is going to get that type every time.
when is the type checking enforced? you'd need an explicit compilation step, but at that point you may as well be using a compiled language altogether.
What they could do is just provide official support for compiling python and allow the programmer to choose between using the interpreter or compiling it. Kind of like what Java already does.
@@ianrust3785 there already is a compilation step though, it’s being compiled to bytecode, the type checking could be enforced then… but maybe i’m understanding wrong…
@@curls6778 That's happening at runtime, while the code is being interpreted, on certain critical pieces of code. To do static type checking the whole code needs to be compiled prior to runtime, where you can output an error message & signal the programmer to fix the bug.
Something they could also do is use a linter & type hints to do partial type checking... this can be done in python already using some 3rd party tools. If these tools were integrated with the interpreter the optimizer could make more liberal assumptions about type-hinted variables.
They decided not to go in this route. I forgot the reasoning presented but this is pretty much a closed case.
@@ianrust3785 I think it does get compiled before runtime … that’s what .pyc files are
23:00 The idea is also used in modern CPUs. It will go down a jump-if branch it has gone many times before while doing the actual test in parallel, and when the test is done, if the assumption was wrong, it will backtrack.
This is literally my thought! It's basically just a branch prediction.
The problem with python is that the efficient type-static code needs to be written in C and put into libraries like numpy, then glued together using a 'glue' which is slow and type unstable. This means you are limited to using libraries in order to have an actual performant code, unless you want to get down to compiled code (which is not what most of the python user-base want or is capable of doing).
The solution to this is allowing optional typing in the glue (python), so that you can actively choose to make bad/slow (bust easy) code or good/fast (but harder) code. This is what languages like Julia have solved from the get-go, where both the high-performance kernel libraries and the dynamically-typed high-level scripts can be coded in the same programming language.
Python is fast and performant for the vast majority of use-cases, and Julia has bugs and has a poor language ecosystem. It takes more than types to make a language, though I will admit for large projects they are sorely needed (but these are 1% of use-cases). You don't need libraries to make python good. Some people choose numpy inappropriately, where even standard lists would be faster (quickly appending values, using disparate objects in your list, etc.). Most things can be done in pure python. Ive even seen entire game engines written in pure python built by solo developers, with really good performance rivalling even that of industrial engines like Unity.
Python has a reputation for bad performance that just isn't true, when you look at it realistically and not theoretically. It aint going nowhere.
@@dreambuffer As a mathematician doing research in computational methods for HPC, I can tell you you are absolutely wrong about the performance of Python versus typed languages. That said, I agree it is good enough for most use cases.
@@jordimanyer8543 I agree, typed is better.
I don't think Python will ever manage to fix a problem so fundamental. It's like asking for natively supported green threads in C - never going to happen. I'm glad languages like Julia exist and I hope they get the mindshare they deserve.
@@dreambuffer bro scanning pixels is slow and takes so much performance
3:15 the technique (re)using previous results is called _Memoization_
Thanks for jolting my memory💡
I figured out by myself that root thing when I was in the first semester of CS and was trying different methods to generate prime numbers. It's what taught me programming logic the most. I used to write down the logic and the code on a notebook and think wow this is complicated, now It's pretty easy to think about those rules I figured out. I just realized I've come a long way.
Same, big moments
simple is a complex subject.
I remember once a gold mining company hired me to optimize a fortran code.
the code was easy to understand but it was 1100 lines long, but besides taking several weeks to process large volumes of data, in some of these cases it crashed.
so I decided to take a different approach and instead of using arrays I used Lists.
The resulting prodigy had 117 lines and was 5 times faster, but if you don't know pointers in fortran it is much more difficult to understand the code.
Ok, I'm really curious how you did that. Arrays in Fortran *should* be super optimised by the compiler; pointers not at all because of lack of data contiguity and jumps. Was it because your data was better modelled by recursive structures?
Lex, please invite some of the Julia lang folk for a chat, like Alan Edelman, Chris Rackauckas, Jeff Bezanson, Stefan Karpinski, etc. I'm sure they'll have a lot of interesting things to say about elegant and performant language design.
You mean, those people who startet their language by copying a totally broken language with ridiculously stupid syntax?
@@hansdietrich1496 By broken language, you mean MATLAB?
@@hansdietrich1496Can you name a single part of Julia’s syntax that is stupid?
I have always taken the approach to code that first, you make it work. Then, you make it user friendly. Then, you make it fast. That's just the way to go. I've always been a bit surprised that compilers and interpreters weren't a bit smarter, in the sense that they don't keep track of the constraints that the code has established... like if in a function a variable is set to an integer, same happens to another, and then later they get added together without any code that could change their type intervening, it can 'know' that they must be integers. It should be possible to track this sort of thing all the way from input (whether from keyboard, network traffic, file, whatever) to use, so that the compiler could figure out what is possible and what is not possible once it hits a certain segment of the code. Instructions don't just return results, they establish constraints and that should change how further code is treated, I would think.
Python is my favorite programming language. I've been coding since I was 12, and I am 44 now. I've done a litany of many different languages, from x86 assembly to C/C++ to Java, C#, LISP, I even really liked Eiffel for awhile. It is a pleasant surprise that Python is so good for beginner programmers, but as an experienced programmer, I absolutely love it because it makes it easy for me to code as I think, and the guardrails that might be useful for a learning programmer, stuff like strict static type checking and such, are simply not mistakes I make any longer, so those guardrails only get in the way. It does shift some burden onto the interpreter, for sure, but I'm simply not going to send in an argument that doesn't have some necessary method I call on it, so I really don't need all the cruft of having to define its type just so the compiler can do some compile-time checking to warn me about it.
I am hoping that one of the parts of the 3.11 speedups focuses on the startup of the interpreter. I know that usually dominates the execution time of many short scripts, with 50% or more of the entire execution time of the script being taken up just getting the interpreter started.
Same approach. I think it applies to anything science, trial and error. By making it works, you understand the matter and will look for a better way by learning from the actual working solution. It has to work first since a proof of a 'solvable' solution to a particular problem.
Always make it right first and in many cases you never should optimize it. About the tracking in the compiler, there are languages which do this. Functional languages which do type inference for example.
@@AlJay0032 I agree. On modern hardware, if your code is slow but you're not dealing with some problem which simply requires a truly profound amount of computation (like on the order of trillions of operations or unavoidable triply-nested loops), it almost always means you chose the wrong algorithm, the wrong data structures, or both. And yeah, type inference is great... but I have yet to see a compiler that takes advantage of the constraints beyond that. It might use a faster floating point low level operation than an integer one on the CPU... but I've never seen one that would optimize away a conditional like "i < 20" based upon there simply being no code paths through the program which could even possibly result in a value of i greater than 19. I don't mean that 3 lines prior i is set to 15 or something, I mean i is composed of digits read from the keyboard and then manipulated, passed through various functions, eventually ending up being passed in and it could be seen by someone who understands the whole process that even if the maximum possible value was input, no matter what the end result would always be less than 20 by mathematical necessity. Most optimizing compilers don't do whole-program dataflow analysis like this. I've just always been surprised when I write some code and I'm like "I know these conditions are going to be met" but then the compiler doesn't seem to 'know' the same limitations. I always assumed compilers were just 'smarter' than humans when it came to code, but hand-tooling low level things still comes in handy, albeit quite rarely nowadays.
@@DustinRodriguez1_0 Switching algorithms is usually easier in a higher language.
What is mindboggling, there could easily be both static typing and dynamic typing in Python. In simultaneusly...
That would be a step closer to the world where you have one language that can be runtime interpreted (fast prototype) and after with little to no changes to compiled to machine code (fast performance).
Type annotation is already nescessary, if you want to do anything complicated with python.
Your problem: It is classical hindsight problem. You has the knowledge of program, but computer is stupid as ever. Knowledge mean calculation and that takes resources. Current interpreter only need to know local namespace and not to know whole program (and without annotation, it is very hard to do with computer). Cost of knowledge of every connection in program can easily be higher than some little mistakes in runtime.
Generality always makes everything slower, and when you implement own knowledge you always make everything faster (generality: error check everything in production cycle. Knowledge: Check integrity only once in factory's terminal, material does not mutate in production.)
But that said, I would love program that analyses every connection in complicated programs and make dynamic visual graph about it. That essentially is same problem.
Guido: we planing to go up to 3.99
Lex: what happens after 99
Guido: probably just 3.100
🤣
a true programmer would have said 3.9A
It's correct, though. They say dot, rather than point, so it isn't a decimal point. You don't have the property that 3.1 and 3.10 are the same thing, or that 3.11 is somewhere between them. Theorem and figure numbers work the same way. I tend to just not pronounce the punctuation at all, but if I did I definitely would never say 'point'.
I love Python
I love Julia more! 😉
@@knofi7052 ewwww
He gets a bit lost in narrow details, and forgets to talk about the bigger picture, or gets so abstract it remains too vague. I mean most of what he said so far until 13:38 can really be said about programming languages in general.
Ok, regarding the optimization, the short summary is he does some kind of caching/memoization and code specialization/instantiation, such that generic functions are implemented in more type specific ways, which allows to remove things a generic function would have to do. 19:30
Also, instead of checking in stackoverflow he reads facebook papers.
Never in my life I imagined Python and fast computation in same sentence
With pandas in 2022 python can process information just as fast as C# for example with 1/10 of the time needed
@@oksatoki But pandas is a framework that utilizes native implementation heavily, as well as numpy. They are not vanilla python. They were always faster than vanilla python, and in fact they were as fast as other languages as you have stated. The problem is that python is not really that fast enough if you are using structres of python only. Like, python numpy arrays are waay more faster than python vanilla lists. And even python has some functions that are implemented in native langauge, which makes them a lot faster. For example, if you had a list of integers with the lenght of 5.000.000, calling the python function sum() will actually invoke the native implementation of the sum function which will perform way faster than just suımming the values in your code with a for loop. Even for loops will be faster than the while loops because their implementation differs in the interpreter level, which is of course impelented in a native langauge.
I guess what I am trying to say is, python frameworks were never the problem. Python itself was the problem. A developer must know the tricks of using the built-in functions rather than implementing themselves, and that is not as easy as it sounds. Some of the functions can be really tricky to use for your data, and wting a function that iterates over each data in the list might be easier for some cases. If the extra performance is required, in that case the developer must use external frameworks like numpy or pandas, or use built-in funcionts and shape their code around that. Which in return may reduce the readibility and maintanability of that code. That is true for all languages, but that scenario is encountered more frequently with the case of Python.
@@oksatoki Yeah but c# feel soo much better to use
"fast" here is a very relative term.
I've read it a lot, on Python forums, and in YT comments so.....
Of course, never in your life will Python itself actually be able to fast computationally. Python is as fast as Basic calling assembler routines, nothing else.
As an aside, PureBasic built by a 1-2 man team results in a compiled .exe that is basically as fast as C, without having to call external libs.
So I was wrong, Python itself is slower than Basic, and with external libs doing the heavy lifting, still nudged out by a Basic.
This whole clip is just a very roundabout explanation of how Python should just really finally have a static-type mode where I can FINALLY declare a function that really only can ever accept two integers and I really mean JUST TWO INTEGERS not any other type Python!! grrrrrr
Yeah lol.
I used to be a big fan of Python syntax. Still find it really expressive and, as dynamic typing language goes, it is probably the cleanest to work with. But I have come to see dynamic typing as a beginner trap. As Guido mentioned in this video, it is certainly handy to have the flexibility of bringing a variable into life without specifying its type. However, the drawbacks are that it is painful to work with on larger projects, especially with third party code as the compilers/linters provide very to no help as to what a valid argument for a given function call. Moreover, the fact that important performance tricks need to workaround this feature is also confirming that dynamic typing is objectively a bad idea on all fronts, except maybe for beginners or prototyping work...
Very interesting talk however.
bro can you explain deeply
@@venkataramanapodugu6211 CPUs expect exact bits. Some high level languages hide that so you can do big number math without bothering with that, but that comes at the cost of speed. Unreal Engine 5 looks great but doesn't use Python for performance.
". As Guido mentioned in this video, it is certainly handy to have the flexibility of bringing a variable into life without specifying its type. "
At the very least you should have to specify you're declaring a new variable though. How does turning typos from hard errors into silent logic bugs help anyone, especially beginners?
@@isodoubIet I think the biggest practical benefit for development an interpreted language, whether static or dynamically-typed is that of iteration speed during development/prototyping/learning because you don’t need to wait nearly as long for a build cycle.
In that perspective, interpreted languages make for faster human iteration, and compiled languages make for faster computer iteration, and static typing is where both the compiler and human can more quickly settle on an optimal solution. Dynamic typing is most immediately helpful while the human is still pondering types, but once there’s been a clear decision, it ceases to have practical value to remain dynamic, at least at the level of simple operations of simple types, particularly scalars and built-in types like strings.
@@strictnonconformist7369 The "iteration speed" benefits drop off very early, around when the code is about a page long. After that the interpreted/dynamic nature slows you down because errors are only caught at runtime after a bunch of processing has happened.
I really like the range of people you interview. Not all are interesting or great, but many are.
This sounds like a subtle insult, I like it
@@AntoshaPushkin ..he seems like a mafia gangster from the 30s, who stepped into a time machine, that travelled to the future to interview the creator of Python.
Prime numbers are amazing. I have used them for a collision system before because you can uniquely identify objects using primes including if they overlap themselves. E.g. you can tell an ID is the same just by checking modulo like 503 and 1006 are the same ID.
Do you know if this technique has any established research term, etc.? I created same idea when I was pondering insanity of multi-event sport scoring.
I named it as prime-substitution, because you can map ordinal-Naturals with ordinal-Primes and then multiplicate scores. Original scoring is saved as a number.
It has limits in space-complecxity as growth of Prime-factorial is insane. And in the end there is still combinatory- problem, where certain combination of event and contender counts still has change of tie. But can be usefull for something else, like unique arithmetic ID:s, but everything prime related are calculation heavy, and most times not usefull.
i find the rienman zeta function as one of the most mind blowing examples of beauty in the world. so aesthetically pleasing. And this beauty is so intrinsically related to the art of building efficient algorithms. Introspecting the unlimited set of general cases of a problem into a single, finite expression is pure gold.
Ok math nerd. Calm down. I could say the same thing about bernoulli numbers or the gamma function.
They are all the same thing really. You should refrase as: "numbers in general are mind blowing...."
it's not really unlimited set of general cases, you're not looking at the values (which are also finite btw, this is CS not math) but rather the types
@@brian8507Wow, what a pointless, useless, and unnecessary response you just wrote.
@@therainman7777 eat a pickle (male part)
@@brian8507 Wow, that was even worse than your first comment. Why do you exist?
As Python developer, I would like to have static typed Python.
Even for begginers I would be helpfull - it's good to know from beggining to be aware of types on variables and function parametrs etc ....
Yep, Pyhon is a neat language but the lack of static typing (or a static-typing-mode) is extremely painful to work with, even disregarding the obvious performance impact
Meh, if you want the performance benefits of typing, you could always just use Cython.
Variable and function types has a cost. It's performance. If this was not a problem Python could have this feature since the beginning, right?
yeah, i'm a beginner/ not even a proper programmer, and even I prefer static typing. I've done some hello world-esque stuff in c/c++ and some unity c# scripting and fell in love with static typing there.
"As a biker, i would like to have 4 wheels bikes." That's basically what you're saying.
The difference between a bike and a car is the number of wheels. If you want 4 wheels choose a car, don't use a bike.
The difference between a dynamic language and the others, is when types are computed. If you want static types, use a compiled language, don't use a dynamic language like python.
I find it so weird when people say "I'm a python developer" while having no idea what Python is...
Python is so simple and brilliant. Guido's a genius.
21:32 can the programmer not flag edge-case functions to force generic interpretation?
Wonder if python should allow optional strong typing. One would only use it when one have a bit of code that is just too slow for its purpose.
Python is a strongly typed, what you probably mean is static typing.
As I have gotten more and more invested into c++ template programming, this discussion reminds me more of a discussion of generic programming in c++, and less of a Python one. I also feel like c++ and python have become closer to each other(in my own view), with "auto", "constexpr", and "std::format". The compiler at compile time in c++ also feels more like the interpreter at run time in python, minus the GIL of course. That is just my opinion and perhaps more of a rambling
Regardless of all the “looks like dynamic” for “auto”, “constexpr” and “std::format” they’re still statically-determined at compile time, while Python is always at runtime, with an observed repetition slightly optimized for, compared to default dynamic assumptions of the language specification itself. The 3 C++ details you mention all make it easier for the human to reason about the code with less cognitive load, whereas the mentioned implementation details of the Python is all about making it easier for the byte-code interpreter to “reason” about the code with less “cognitive” load.
@@strictnonconformist7369 Yep I agree. I just think its sort of interesting that parts of this vlog just sort of felt like it could have come out of a cppcon talk. I was looking at the matplotlib cpp source the other day and all the templating just sort of reminded me of how "x=0" in python feels like "auto x=0;" in cpp from a coders point of view. Like you pointed out, it has nothing to do with what is actually going on when it is being used, it just sort of "feels" more similar now compared with old 90s cpp era code writing. Things like smart pointers, auto type deduction, lambdas, all just feel sort of "Pythonesc"(totally not a word) but maybe that has to do more with me learning Python first before I got seriously into cpp. Who knows?
@@scienceandmathHandle if you want a truly disorienting language for syntax and keywords, go with Swift: it’s sort of like English in that it assimilates words/concepts from many other languages Borg-like while having some things all its own. It has type inference which in theory makes it less explicit for types for writing the code as someone reading the code, but that’s also been known in past versions (I need to check in the current version) to be less than ideal in implementation, resulting in absurdly long compilation/build times, assuming it doesn’t tell you the expression is too complex, if you depend too much on type inference.
Swift is a Swiss Army Knife of languages in that, like C++, it’s truly multi-paradigm, and for so many things, there’s not a single “only use this” way of doing things. For supposedly being an easier language to learn, it has a rather large amount of syntactic and semantic complexity. There are parts I love about it (type inference is both a blessing and a curse) where it has grabbed things from elsewhere. It’s even more flexible than C++ in some ways in that due to needing backwards-compatible with Objective-C, it’s simultaneously able to support SmallTalk message type OO that’s not so strictly-typed, while also being able to work with more C++-like strictly-typed objects that help for performance. Like Objective-C evolved to have before the transition to Swift, it uses Automatic Reference Counting, with a few more tweaks: it’s more like COM than the garbage collection of Python or other languages, and is much more deterministic. And yet, Swift, meant as a systems language, doesn’t exactly have a small runtime, so isn’t nearly as suited as C/C++ for embedded microcontroller software. I’d expect Python may be smaller.
@@strictnonconformist7369 Thanks for your feedback, and take a thumbs up on me! I would like to check out Swift sometime when I get the time. I hear its pretty cool. But unfortunately it is not what what we use at work. I wish I had the time to learn "GO" and "Rust" too! There is only so much time in the day though. But there is a general trend right now towards .NET at work that I may not be able to escape from. So I guess I will see what the future holds.
So with 100% code coverage, all types should be known and could be automatically added to the code to speed up first runs on other machines. from typing import Final can be used to create const vars for futher speedups. Or switch to Rust and only mark some things as mutable. V and Nim have simpler syntax, though, but even contracts like Ada/Spark and its mathematical correctness can be generated.
But python allows arrays of heterogeneous types, right? So adding two vectors doesn’t mean it is adding vectors of integers, as elements could be a combination, for example, of integers, BigInts, strings and even matrices. Just as an example.
Inferring the types may seem trivial, but the way a language like python handles typing, it is not.
100% code coverage doesn't mean 100% branch coverage. Formal verification is close to impossible for python, because there might always be something that goes wrong. One solution could be to have everything bear-typed (assert the types at runtime), but it can be quite expensive.
@@aedieal MyPy does static type checks with provided type hints, and Cython uses type hints to optimize transpiling to C.
What about input data lol
@@What-he5pr input() for utf8 and ctypes for C types.
Thinking about the add example from the perspective of what a CPU is capable of, most CPUs can do multiple math operations per cycle without SIMD instructions and many more per cycle with SIMD.
What was described here for operators is maybe tens of cycles (or maybe over 100 cycles) for one math operation.
The described operator process is several orders of magnitude slower than the theoretical maximum of the hardware.
For python, assuming a JIT, why not approach the performance optimizations as how to get close to theoretical maximum capability of the CPU (for tight loops) versus tricks to do better but still orders of magnitude slower than CPU theoretical capability?
My understanding about the ethos of Python is historically do everything as simple as possible, but no simpler. This certainly has a performance cost.
I won’t pretend to know the long-term Python implementation objectives, but a true JIT compiler definitely is not that philosophy.
There are scenarios (hard real-time) where consistent known performance is more important than amortized better performance that has performance glitches. I was amused lately to learn there is “circuit Python” intended for embedded microcontrollers. A Python with a true JIT is something I’d never expect to fit in such a scenario. There are certainly great advantages to a language design/implementation that is sufficiently minimal yet complete that you maximize its reach as-is with one implementation regardless of actual machine platform. I’ve not checked if they’ve added a meaningfully-larger amount to it since I used it 10 years ago, but as an example, Lua has in the past been embeddable as a single 29kloc standard C source file. It’s beautifully-portable and embeddable, and more than fast enough for most scenarios, and doesn’t suffer from the GIL, making it easier to work with multiple threads (though the language doesn’t officially support them) by using multiple instances in the same process, as the host process can easily take care of synchronization.
Mike, I get your point. And I do not understand "as simple as possible, but no simpler". Isn’t "but no simpler" redundant?
I don’t really see consistent performance for "hard real-time" programs as precluding the larger picture optimizations Mike alluded to. A much faster loop that does several integer optimizations will always perform that way, for integer data types. If the data types happen to be matrices or strings or something, the program will perform consistently, but slower for those types.
Python being as fast as go would be complete game changer
Is it possible or just a dream?
Not with CPython, no. Pypy maybe but it has other drawbacks.
It is just a bit faster, but you still have other programming languages with performance out of the box.
Right now, pypy is not to far behind cPython. Two minor revs behind 3.11
@@ElPrincip6 no chance, go is compiled to machine code whereas python is interpreted which adds a layer of indirection
Simplicity vs performance
why so? As a C# developer I dont understand why you(python community) speaks that it is impossible to fit both simplicity and perfromance
@@MrFrimko C# is not interpreted in the same way Python is, so it's not an apples-to-apples comparison. Also, simplicity often means the most straightforward implementation whereas the performant ones are often way more complicated. String searching and matching would be a good example. Matrix multiplication algorithms also fall into this category.
~ 18:40 - This optimization _does_ emanate a hint of JITC aroma.... And, as somebody noticed, of branch prediction... 😀
A thought I had is why not reapply the addition operator function when the type of the variable gets reassigned? In theory if the type never changes, there wouldn't be a need for all of this accounting. I'm sure there's a reason for this.
How about an option to define types in python to increase optimisation?
I wonder about this too. Pretty sure they will use break compatibility as an excuse
"people like fun" these nuggets are the knowledge bombs I'm here for
I don't like it
Yeah… Guido’s continuously pulling us back down to earth. He’s right that there will always be people doing unrealistic stuff to try and prove a point, even a redundant one. It’s like complaining about the top speed of a bus.
8:33 what is the interpreter
I was like, "Oh, cool! This would be a good talk to listen to while defining octonion addition and multiplication in Python."
Imagine my reaction at 14:00
Lol. Just heard the comment “ better to assume the weather today is the same tomorrow as it is today, because that is better than staying with a random value” to which I say not in Scotland is not. 😂
I didnt know lex was this tech savvy.... new found respect for the man
@Armel Talla and also lost a lot of reputation by going to the press instead of peer review at that same institution.
I‘m a little confused. I thought the more compute intense a task is, the lower is the time portion taken by the interpreter. This would imply that low compute intense programs benefit more from 3.11. Is my assumption incorrect?
my code for the prime number example:
from math import sqrt
gol = int(input("max broj je:"))
i=9
prime = [3,5,7]
while i
Guido talks as fast as the Python interpreter runs!!
This was amazing! Thank you!
I waited him to ask “why not use optional type annotations in code?”
Lol good question
does mypy (variable typing) help?
Not much. Unless types are enforced by the compiler itself, type annotations are really for high level readability and documentation. I like them, and I use them in python, but I dont rely on them that much. And I prefer static typing
Where did you find this idea to cache your operations, to avoid doing unnecessary work?
Sounds a lot like it comes from JIT compiling
Gotta say, Guido is way nicer than I expected.
thank you, Guido van Rossum and Lex Fridman
why is php still faster?
Well, I don’t know. Having a lot of frustration with Python 3.11.
Changes to Seaborn plots that no longer support positional x and y values requires a lot of working code changes.
Pandas pd.read_hdf no longer works, no module named ‘tables’, pip install pytables.
But that gives no matching distribution found for pytables,
Can’t install torch or PyTorch, TensorFlow, etc, etc…
This might take a little time until they fix it. For now I think it is better to stay on more stable versions of previous Python.
Python sucks because every single version is only properly compatible with itself, I don’t get how anyone can use it when everything breaks in the next MINOR version
@@Fantaztig Yeah, it is probably my biggest issue with actually running Python code done by others. The language devs (or publishers) should be more careful about how the versions handle or try to handle older code..
That was interesting. Thanks for sharing!
Yep, just add performance, static types, no GIL, proper threading, maybe LINQ, and soon, you'll have what C# had 15 years ago. Python is a great example of why popular is not good (and then there's JavaScript, lol)
I remember reading about tagged operations, i think it might have been called, 45 years ago (in Communications of the ACM? Perhaps 1977?).
But implemented in the hardware, machine language.
Exacly the same idea, but implemented in the machine architecture, instead of in software.
I don't think any computer ever implemented it. But I thought it was a good idea!
Interesting topic and guest!
I just started learning python. Only other thing I know is matlab which can be annoying
And expensive
@@wartem yeah fortunately my school covers that for now
So basically start using type hints in Python so that you know you are sending same types all the time.
Hey Co you're doing great job by doing these 👍
I am happy about it because this is good for video game development.
Is possible to install PyTorch for python 3.11?
Python is a great language and its not that slow as some people have said it was..
Lol, it's many times inferior to the C# and C++ programming languages
So as I understand this as a very green Python dev.. the interpreter stops checkin both operands types after an arbitrary amount of runs. Meaning it assumes types after completing the operation without errors.
"I borrowed things left and right...cut corners". I am not alone hahaha!
Thank you Lex and Guido
"Probably go to 4.20" Underrated line
the whole interview is so amazing it really makes you wonder how the f***k we live in a society where Kanye West gets much more credit and attention than one of the guys that genuinly contributed to shape the world we live in.
This is how the history of mankind has always been. In the short term we remember the clowns (entertainers) but in the longterm remember the leaders and the scientific progress.
It’s slow as balls. Who said it was fast?!?
23:53
His personal website is my favorite, especially as a developer
I really love Python and it would be soooo amazing if it was 5-10x faster. Thats enough
If by fast you mean slow, then yes
5:14 segmented sieves
Python is viable for many of its modern uses because of performant C++ library implementations underneath it. Listening to this talk about complex type abstraction at the bytecode level you know that "fast" is a relative term here.
short answer: because python 3.10 is so slow
What about add an integer to a float?
Thank you Lex Luther for this useful clip. Sincerely, superman.
So uh... why is it faster?
Is annoying when people with a little wrasp of programming says python is not a fast. Chose the right tool for the right job and live with it.
guido went completely over lex's head in this conversation
TDLR, it the magnesium, it makes its vowels move faster
Como puedo escuchar este video en español ?
Anyone know what type of math is best for coding?
17:21 'Now, you write your little Python program' - I felt like he was looking down in my soul there for a moment 🫢
I hope I live to see the day of python 3.420 🍀
After Python 3.11 comes Python 95. That's for sure 🤣
Choose simplicity rather than performance initially
C isn't a low level language.
Low level language are for example all the assembly
High level language are for example all languages that are compiled into assembly.
now if you want a general rule to understand how to identify low level vs high level and this was the consensus in every compiler book before the internet allowed for the distortion of terminology.
there is something called "translation layers" all this translation layers exist both in hardware or software. If your language is meant for use by translation layer in software and requires a complicated syntax analysis then is high level. If your language is meant for a translation layer in software that requires a simple 1 to 1 translation like assembly or is meant for hardware interpretation then is low level even if the translation is complicated. In the past some mainframes had BASIC as their assembly.
C is meant to be translated by a compiler (offline translator) offline translator means that the translation takes files and dumps files
Bash is meant to translated by an interpreter (online translator) online translation takes single instructions or files and performs the actions immediately.
Java/python/Ruby are hybrid of offline and online translation, Java is right in the middle because it has a compiler into bytecode and then you distribute the bytecode so the translation and execution are not on line. Ruby and Python translate into bytecode internally and keep that in memory and then execute the bytecode, so they are hybrids but are closer to online translators than the middle on/off line translation.
Now, is possible to make an interpreter for all compiled languages like C, and run them but they are not going to have the same semantics.
"low level" is context dependant. C is considered low level in most practical cases.
More memory usage for more time efficiency
If you're starting to learn Python, there's a free online course offered by Harvard and is taught by a phenomenal professor David Malan*
David Malan* .. the best CS teacher I've ever come across
Wow...I learned alot.
The guest is very charismatic
Saint Giudo. Thank you.
Isn’t this just a kind of branch prediction?