Rock Solid Python with Python Typing Transcripts
Chapter: Tools Based on Typing
Lecture: Beartype Speed Test

Login or purchase this course to watch this video and the rest of the course contents.
0:00 We just saw how to use bear type and it's pretty cool that we just put this decorator
0:05 in here and no matter how our code is used, it can't be used incorrectly. However, how much of a performance hit is there? Turns out it's pretty low.
0:17 The bear type page said very minimal. Well, one person's minimal is another person's really important. So let me add a little example here.
0:28 First thing I'm going to throw in is this thing I called timed and it's just a decorator
0:32 that I wrote that when you throw a function on it, it runs the function and then prints
0:37 out how long that took to in terms of milliseconds or the 10th of a millisecond. So that's cool. And then over here we have a runtime speed.
0:47 This one has no bear type on it at all, but you can see what it's doing is it's calling just doing a bunch of like useless busy work really.
0:57 What it does is it's given a list of counts, basically, and it says for each one of those,
1:02 we're going to go through and for that many times, we're going to call these two functions. This one's going to do some math-like things with numbers.
1:11 This one's going to do math-like things with strings, so build up huge, pretty huge actually, strings.
1:19 For however many times, it's going to come up with 10,000 strings each time it's growing. is pretty computational.
1:27 The idea is like it simulates doing a web API or a database call or an external API or something that there's a little bit of work
1:34 and it's not just like, hey, how fast is a for loop run in each language? Well, that's not really what we care about that often.
1:41 Sometimes, but most of the time, no. So let's just run this real quick here. Remember, no bear type here.
1:49 we run it, it takes one second and 118 milliseconds. Keep in mind, I'm doing a recording and things like that.
1:59 So it's not exactly just a system at rest, right? I'll run it a few times. Let's see what kind of numbers, but 1.1 seconds is looking,
2:08 looks like pretty stable there, doesn't it? That's cool. Okay, so here's the question. How much worse will it get if we run this with bear type?
2:18 Okay, so call it speed checked, like that. And all we're gonna do, the order is important here. We're first gonna have our regular function,
2:30 then we're gonna have at bear type. Did it import it correctly? It did, okay. So these are like onions, right?
2:40 First thing we're doing is we're calling this function, then that's decorator wraps collector top,
2:45 returns another function which is wrapped by the timed function.
2:50 That's important because we change the order, we're not really timing the bear type aspect.
2:56 All right, let's go over here and we'll put bear type on this. In fact, let's not even put it on this one just to be 100% sure.
3:07 This is this function that's called here. This is this function that's called here. Let's run it. this checked one.
3:17 Run it again. It took 1.13, so we had 1.135 instead of 3.3. I mean, there's no way
3:30 it's gonna make it faster. It's doing more work. So you can see it's not adding really
3:35 much overhead at all. Now, do I recommend every single function that you write
3:39 gets this bare type on it? No, probably not. If you've got a really nice Python type, decorated
3:48 annotated set of code that maybe is protected with my pie or your editor and you've run
3:54 the total project checking once or twice and then you kind of keep it hanging together.
4:00 You don't need every function in there to be running that way. Really mostly what you
4:04 need with this looking inside a collections caveat, of course, mostly what you need is
4:11 just the outside functions. Like if you're creating a data access layer, well, maybe
4:15 just the top level functions that people call like find user by ID, find user by email,
4:21 right, you could say the ID must be an int. And email must be a string, do that with runtime
4:26 checking. But from there on, you've got your Python type hints and your my pine everything
4:31 telling you, if you get into this function correctly, from here on out, it's safe. So
4:37 I think a really good pattern with bear type is like protect the boundary, if the inside
4:42 stuff is already validated with Python types. But that said, that's kind of what we have
4:47 here so far. Let me make it a little more intense, right? So let's go down here and
4:52 say that this thing is going to also be a bear type protected function. I'll call this
5:00 extract the method, call this math stuff. And this is going to be an int. And then groups
5:08 can be a list of float. And we'll bear type that. So in this case, we'll say,
5:18 for every one of these plus equals one. And then let's do down here the same thing.
5:28 didn't really matter, but we can put a list of stir on there like that. And I guess total is
5:35 just gonna be one, in this case, or zero, this one. Here we go. Let's run again, see where we are. Now we're up to 3000 operations. And
5:54 Just see if we get any difference. Zero difference, right? No difference, no difference here. That's for protecting the boundaries. That is a lot.
6:05 And one more time, let's suppose somewhere in here, instead of passing an int, we're gonna pass a string of that down there. Whack.
6:16 The parameter 20 in the string, as a string, violates the thing that it must be an int because you made it not an int. Silly, don't do that.
6:26 Right, how awesome is this? I'm actually really, really excited about bare type. I think it's going to be something that I adopt in some of my code.
6:35 It looks solid. So again, if this was a dictionary of lists of int, it's not going to check that. So you might need to put bare type
6:45 down a little bit further down. Of course, if you're using things like pydantic, you know, it's not going to make it that far if it's incorrect anyway.
6:54 So you can mix and match these, but bare type on the boundary, it looks like a pretty solid idea to me.


Talk Python's Mastodon Michael Kennedy's Mastodon