 Hello everyone. So in the last video we talked about kind of the mechanics of how the array-based list Which is what pythons regular list uses How those what the mechanics of that data structure are okay? So what I want to show you now though is a little Python program And you can download this off of canvas and play with it that actually shows you what it the difference between Big O of 1 and big O of n really looks like on a real machine When we talked about T of n and counting computational steps and big O of n we said You know, we don't count these things in real time Because everybody's computer is different it can run some computers run faster than others Some people have other programs running in the background that can change things So actual units of time like seconds are not good measures and that's true But we can still demonstrate the real impacts of big O of 1 versus big O of n On a real machine, right? So let's do that with this timer program And I encourage you to download it and play with it yourself Okay How does it work? You I'm not going to expect you to know all of this, but I want you to kind of follow along so How does this code work? What is it going to do? the first thing I do is I'm setting this variable to a certain size and what I'm do up here is This is kind of some this is called a list comprehension in Python You're not expected to know these things. They're kind of cool You can look them up chapter one of your book talks about them. They're pretty neat But you don't need to know them. Okay, but what is this doing? What is this lion of code do? What it does is it generates? This many whatever size is Random numbers between zero and ten and shoves them into a list. That's it, right? so it's creating a list here with this many numbers in it and For my purposes, I really don't care about How what the numbers are or how I only care how many there are right? So that's all I care about I'm going to use this this random nums to help me do my testing Okay, so I want to have lists of different size to do this testing with That's what's going to demonstrate the big O. Okay. All right, so I generate this list that I'm going to use to test And again the contents of it aren't important really the size of it is Okay, now I'm going to start a stop watch. Okay, um, so I print out starting timer And then I record the current system time So python has this built-in module called time and it has a method on it called perf counter for performance counter And all this really does is it asks the clock that's inside the computer? Hey, what time is it write this in nano second and it is down to that level of precision What time is it this nano second? and we're not talking about Like it's 12 30 in the afternoon. It's you know, just I need to mark this precise instance in time And we grab it and we store it in a variable. We call that the start time Okay, now down here below this is where we're going to play around with the big O of 1 the big O of n operations So what do I do? I make a new empty list And for each num In random nums, right? So This means that the length of random nums is our n When computing big O F of n This is n is the input size n is our n The input size that drives Uh efficiency All right, let's put it that way right All I am doing here is appending I loop through this list and I append Each element of the list into a different list Okay, it's a It's a silly kind of nonsensical thing to do But what I want to show is that append What is the big O of append? Well, it's big O of 1 So that means that As The size of n grows here The time it takes to append Should actually not change much, right? It shouldn't change whether I'm appending to a list With a million items a billion a thousand or ten the time should be pretty much the same, okay? So that's what I want to demonstrate All right, so I do a bunch of appends, right that are dependent on how many items are in random nums Okay, but it shouldn't matter. That's what we're saying with big O of 1. It shouldn't matter how many items are here Okay, so we'll do that experiment. I will grab the time that we stopped What's the instance of time that we finished everything all this appending stuff? And now how much time actually transpired and this will calculate it and print it out, okay? All right, so let's run this with a list of a thousand items. I'm generating it and then I'm going to append them to a new list Okay All right, so I run it with a thousand items And this took 0.00155 seconds to run That's 155 micro seconds That's an imperceptible amount of time to you as a human being the computer can recognize it But it's so short. You can't you can't even cogitate what it is. Okay fast If you run this code yours is probably going to be a little bit different. Okay, that's fine Um because again, it depends on your computer how fast your computer is What else you're doing if you got fortnight running in the background or you're rendering some Big video in adobe premiere. It's going to be slower. That's okay um Let me increase this size now again what we're testing here is list dot append and we're asserting that it's big o of one So the input size shouldn't matter. Okay, I've got about 155 micro seconds with a thousand items Let's increase it to 10,000 Okay, it's a little bit longer Just a tiny bit We're up to a millisecond now. Let's run it again Okay, one point 1.288 milliseconds. Let's run it again. You can even see the variance in just my little computer here, right? Um every run is a little bit different just based on what windows is doing in the background So it did actually make a little bit of a difference A little bit big o of one here um All right, now it's down to just one millisecond Let's up the game to a hundred thousand Okay, this kind of makes sense in a way though, right? Um Big o of a hundred thousand it's this is a hundred times bigger than it was with just a thousand So there's a constant factor at play here. Remember what does big o mean? It means that your algorithm Is less than some Function times a constant factor. Well, I'm increasing things by a constant factor here, right? So I I do expect things to kind of move up just a little tiny bit some of the time, okay Just a little bit now what's actually happening though the reason that append is taking a little bit longer time is because of Remember every once in a while when you append and when you grow you run out of space and then it has to copy it to a new thing That's what's happening here. Um, let's try it with popping. Okay, so If I go back what does popping do popping removes from the end of the list So let me just instead of appending to test the list. Let me um Let me try to pop here From random nums this may not May not allow me to do that. Actually, what I'm going to do is I'm going to make test list be a copy Of random nums random nums.copy And I don't want to start include that in the timer because that might take some time But now let's pop let's run this Okay, so popping I popped a thousand items and it took a hundred microseconds Let's pop ten thousand items It took one millisecond a hundred thousand items it took 12 milliseconds 13 milliseconds So the size is is kind of mattering here now. It's taken a lot longer, right? But I'm changing by a constant factor. This is constant time. So that's It's okay. It's not bad and you can see it's fast too, right? It's fast um Let's try something that is big o of n Okay Let's get back to where we were um Instead of appending to the end, which is big o of one our other option for inserting data into the list is to insert it Okay, so let's insert At index zero every number. Okay, so basically i'm creating a copy of this list Um, but in reverse order. Let's run this. Okay size a hundred Still fast right still fast size a thousand Still pretty darn fast, right just 300 microseconds. It is a little slower than appending Remember when we talk about big o one of the things that we asserted was We only care about large values of them whenever things really start to get up That's when we're going to see things really start to slow down right because computers are inherently fast They can do billions of operations per second We're not really going to feel the pain until our size gets up around 10,000 or 30,000 or 100,000 So let's get up to 10,000. Let's see if we notice a delay Okay, not too bad. We're down to two hundredths of a second though Okay, compare that to append. What was append append was a lot faster than that Two hundredths of a second to insert One millisecond to append. Hmm Let's bump this bad boy up to say 50,000 Half a second. Okay getting much slower now Okay, inserting a hundred thousand items Took almost two seconds on my computer Appending 100,000 items takes What 15 milliseconds? That's a big difference, right? That's actually a big difference May not seem like a big difference to you But if you're sitting there waiting on your computer to calculate something and it takes two seconds to calculate something That's kind of slow in computer terms, right? Let's bump this up to a million Okay And we're gonna have to sit here a little bit, you know, probably 20 30 seconds or so Um before this comes out Um So your choice, what am I trying to get at here? Your choice of Algorithm matters Insert is a big O of an algorithm Append is a big O of one algorithm. So given the option You should append, right? We're always going to try and do the most efficient thing Now it could be the case that the most efficient thing Doesn't solve the problem you need to solve That's a limitation of computing But your goal as a computer scientist is someone who does solve problems using computers Is you have to recognize and understand that there are trade-offs And that there are sometimes better ways of doing things for solving really common problems So in the coming videos, we are going to talk about Um some ways to solve kind of common challenges you run into in computing And your choice of how you solve them is going to say whether your solution is good or not, right? We're kind of evolving to the point where just getting the right answer is not going to be good enough This is bad, right? I'm inserting a list of a million items a million items is nothing to a computer It's one megabyte your computer can store 100,000 megabytes At least right or a million megabytes So this is nothing this is no size at all appending here I get the answer real fast inserting. I've made a huge blunder, okay So we want to make sure we understand what we're doing when we're writing and using algorithms I'm tired of waiting this thing's still going it'll finish eventually, but I don't have the time But think about, you know, why is this so bad? It's because when I insert at the bottom when I insert at index zero I've got to move everything after index zero down a slot Why is my list grows and grows? I got to move more and more and more Not fun, right not fun Anyway, all right, that's it play around with this see if you can make Look at the other big O of n algorithms. Look at removing from a list. That's another big O of n algorithm Um, try it out compare it with another big O of one algorithm like popping And we're signing to Reading variables printing out variables that you get out of the list, okay Play with it. Make sure you really understand what's going on with this big O of 1 versus big O of n stuff And know the big O's for your array list operations. All right. See you in the next video