1 00:00:06,670 --> 00:00:09,670 - We just reviewed around how mechanical sympathies 2 00:00:09,670 --> 00:00:13,210 of using arrays and slices and maps a little bit, 3 00:00:13,210 --> 00:00:15,340 and we showed how these mechanical sympathies 4 00:00:15,340 --> 00:00:19,070 are real, as it relates to hardware that handles caching. 5 00:00:19,070 --> 00:00:22,360 I wanna try to sum up a lot of what we've talked 6 00:00:22,360 --> 00:00:25,230 about up to this point, while using arrays, 7 00:00:25,230 --> 00:00:27,730 and to get back into some of the conversations 8 00:00:27,730 --> 00:00:32,120 we started earlier around value and pointer semantics. 9 00:00:32,120 --> 00:00:35,110 There's a lot here in this section I wanna cover 10 00:00:35,110 --> 00:00:38,170 that's gonna give us a really strong base foundation 11 00:00:38,170 --> 00:00:40,960 as we move forward and learn about it in a design 12 00:00:40,960 --> 00:00:43,130 and our data and our data structures. 13 00:00:43,130 --> 00:00:46,000 Let's start with this piece of code here. 14 00:00:47,930 --> 00:00:51,080 We're not doing anything special on line 14. 15 00:00:51,080 --> 00:00:53,980 We're declaring an array of five strings, 16 00:00:53,980 --> 00:00:57,387 again five being that constant of kind int. 17 00:00:57,387 --> 00:00:59,370 The compiler knows about the size of an array 18 00:00:59,370 --> 00:01:01,600 in compiled time, because the size of an array 19 00:01:01,600 --> 00:01:02,990 must be known in compiled time. 20 00:01:02,990 --> 00:01:05,450 You can't use a variable for an array. 21 00:01:05,450 --> 00:01:07,640 We will be able to do that with our slices 22 00:01:07,640 --> 00:01:09,140 we'll see in the next section. 23 00:01:10,580 --> 00:01:15,510 When I see line 14, what I see is 40 bytes of memory. 24 00:01:15,510 --> 00:01:18,250 Remember, a string is a two-word data structure. 25 00:01:18,250 --> 00:01:20,110 We're on our playground. 26 00:01:20,110 --> 00:01:24,800 What I see is starting an index one, two, three, four, 27 00:01:24,800 --> 00:01:29,670 I see five strings laid across contiguously, 28 00:01:29,670 --> 00:01:34,670 all set to their zero value which makes them empty strings. 29 00:01:34,970 --> 00:01:37,660 This is what we have after line 14. 30 00:01:37,660 --> 00:01:38,540 This is what I see. 31 00:01:38,540 --> 00:01:43,010 This is our fruits array. 32 00:01:43,010 --> 00:01:46,880 I wanna focus on line 15 for a second. 33 00:01:46,880 --> 00:01:51,880 What we see on line 15 is a literal string named apple. 34 00:01:52,400 --> 00:01:54,960 That's also a string that's gonna be appointed 35 00:01:54,960 --> 00:01:59,810 to a backing array of five bytes apple 36 00:01:59,810 --> 00:02:01,910 and we're gonna have the number five. 37 00:02:01,910 --> 00:02:04,550 It's a literal string, it's a constant. 38 00:02:04,550 --> 00:02:06,630 That data will be in our data segment. 39 00:02:07,490 --> 00:02:10,780 Let's just imagine right now that we have our string, 40 00:02:10,780 --> 00:02:13,630 we've got this pointer, there it is. 41 00:02:14,830 --> 00:02:17,830 One of the questions I always like to ask in a class 42 00:02:17,830 --> 00:02:19,920 is what is the cost, where we're talking 43 00:02:19,920 --> 00:02:21,960 about engineering costs and benefits, 44 00:02:21,960 --> 00:02:25,570 what is the cost of this assignment on line 15? 45 00:02:25,570 --> 00:02:29,180 Remember, an assignment is a copy operation, 46 00:02:29,180 --> 00:02:33,350 so the question is what is being copied on line 15? 47 00:02:33,350 --> 00:02:35,240 This string is really the combination 48 00:02:35,240 --> 00:02:36,720 of two data structures. 49 00:02:36,720 --> 00:02:40,730 It is the string value and a pointer to the backing array. 50 00:02:40,730 --> 00:02:43,190 What's really interesting here is that the cost 51 00:02:43,190 --> 00:02:46,880 of this is just the two-word data structure. 52 00:02:46,880 --> 00:02:50,910 All we're going to be copying is the A, or 16 bytes, 53 00:02:50,910 --> 00:02:54,780 depending on the platform of memory that's associated 54 00:02:54,780 --> 00:02:57,950 with the string value, which tells us right away 55 00:02:57,950 --> 00:02:59,610 something very special. 56 00:02:59,610 --> 00:03:04,610 Remember, strings, I'm sorry pointers are for sharing. 57 00:03:04,960 --> 00:03:08,060 Pointers are for sharing, and if you look here, 58 00:03:08,060 --> 00:03:11,680 this pointer is giving us the ability to share 59 00:03:11,680 --> 00:03:16,680 the backing array across these two distinct string values. 60 00:03:16,950 --> 00:03:19,790 Remember, pointers are for sharing and that sharing 61 00:03:19,790 --> 00:03:21,870 gives us a level of efficiency. 62 00:03:21,870 --> 00:03:24,260 I only need one of these backing arrays 63 00:03:24,260 --> 00:03:27,470 for the two string values that we have. 64 00:03:27,470 --> 00:03:31,810 Go only uses a four statement for all of its iteration. 65 00:03:31,810 --> 00:03:33,840 You can use the four in a traditional way, 66 00:03:33,840 --> 00:03:36,240 like I'm showing you on line 31 here. 67 00:03:36,240 --> 00:03:38,666 You can also use four (mumbles), 68 00:03:38,666 --> 00:03:41,680 where you just specify the condition. 69 00:03:41,680 --> 00:03:44,290 But, the four range is a very special 70 00:03:44,290 --> 00:03:47,600 and powerful iterator in Go. 71 00:03:47,600 --> 00:03:50,720 The reason why it's so powerful is because the four range 72 00:03:50,720 --> 00:03:53,540 comes with two different semantics. 73 00:03:53,540 --> 00:03:55,080 Here we go again with semantics. 74 00:03:55,080 --> 00:03:57,600 There are value semantics and pointer semantics 75 00:03:57,600 --> 00:03:59,530 associated with the four range. 76 00:03:59,530 --> 00:04:03,200 Remember, again, when I talk about value semantics, 77 00:04:03,200 --> 00:04:05,780 what I mean is that every piece of code 78 00:04:05,780 --> 00:04:08,890 is operating on its own copy of the data. 79 00:04:08,890 --> 00:04:11,470 As we transition across program boundaries, 80 00:04:11,470 --> 00:04:14,280 in between functions, as we do things, 81 00:04:14,280 --> 00:04:17,300 we're operating on our own copy of the data. 82 00:04:17,300 --> 00:04:18,730 What are the benefits (mumbles)? 83 00:04:18,730 --> 00:04:21,940 Again, we get the sense of immutability, isolation, 84 00:04:21,940 --> 00:04:24,920 mutation is isolated, and we don't create 85 00:04:24,920 --> 00:04:26,440 these side effects. 86 00:04:26,440 --> 00:04:29,720 But, we also have the ability to have pointer semantics. 87 00:04:29,720 --> 00:04:31,040 What is pointer semantics, again? 88 00:04:31,040 --> 00:04:32,760 It means that we're sharing. 89 00:04:32,760 --> 00:04:34,750 We're gonna get efficiencies. 90 00:04:34,750 --> 00:04:38,740 But, because we're sharing it, mutation has to be dealt with 91 00:04:38,740 --> 00:04:40,800 either through synchronization, orchestration. 92 00:04:40,800 --> 00:04:43,900 We have to understand the effects mutation can have 93 00:04:43,900 --> 00:04:46,570 because they can create side effects 94 00:04:46,570 --> 00:04:48,610 throughout our application. 95 00:04:49,640 --> 00:04:53,340 What you're seeing on line 22 is the value semantics 96 00:04:53,340 --> 00:04:55,240 form over the four range. 97 00:04:55,240 --> 00:04:57,300 There's a few things happening here. 98 00:04:57,300 --> 00:05:00,110 We're gonna be ranging over this array 99 00:05:00,110 --> 00:05:01,920 of strings called fruits. 100 00:05:01,920 --> 00:05:04,330 On every iteration, we're gonna get the index position, 101 00:05:04,330 --> 00:05:06,250 zero, one, two, three, four. 102 00:05:06,250 --> 00:05:08,740 This local variable to the four loop. 103 00:05:08,740 --> 00:05:11,160 Notice, we're using the short variable declaration operator. 104 00:05:11,160 --> 00:05:13,620 This local variable to the four loop is going 105 00:05:13,620 --> 00:05:17,770 to be a copy of every value that we're iterating over. 106 00:05:17,770 --> 00:05:21,480 In other words, our fruit variable, 107 00:05:21,480 --> 00:05:26,330 that ends up also being a two-word string value 108 00:05:26,330 --> 00:05:29,170 and a copy as well. 109 00:05:29,170 --> 00:05:32,030 After that, if you notice, we now have 110 00:05:32,030 --> 00:05:35,300 three string values on the board, 111 00:05:35,300 --> 00:05:40,300 all sharing very efficiently this one backing array. 112 00:05:40,380 --> 00:05:41,790 We're not done yet, because I want you 113 00:05:41,790 --> 00:05:43,570 to look on line 23. 114 00:05:44,440 --> 00:05:49,090 On line 23, we're calling print, and when we call print, 115 00:05:49,090 --> 00:05:51,700 look at what we're doing in the second parameter. 116 00:05:51,700 --> 00:05:55,230 We are passing fruit, but what are we really passing, 117 00:05:55,230 --> 00:05:56,280 what is the data? 118 00:05:56,280 --> 00:06:00,220 We're passing a copy of the value of fruit. 119 00:06:00,220 --> 00:06:01,290 What does that mean? 120 00:06:01,290 --> 00:06:06,290 It means in the stack frame below us, we now get a second, 121 00:06:06,940 --> 00:06:11,940 or now one, two, three, four, our fourth string value 122 00:06:12,070 --> 00:06:15,650 that is sharing the backing array. 123 00:06:15,650 --> 00:06:16,860 Think about this. 124 00:06:16,860 --> 00:06:20,530 I've got this on our stack frame here, 125 00:06:20,530 --> 00:06:23,140 this on our stack frame, this on the data segment, 126 00:06:23,140 --> 00:06:27,132 and now this is in the stack frame below us. 127 00:06:27,132 --> 00:06:31,370 Four string values sharing, with efficiency, 128 00:06:31,370 --> 00:06:32,480 the backing array. 129 00:06:32,480 --> 00:06:35,490 What I really want you to notice is how powerful this is. 130 00:06:35,490 --> 00:06:37,730 I've got five values on the board. 131 00:06:37,730 --> 00:06:40,810 One, two, three, four, five. 132 00:06:40,810 --> 00:06:45,220 Yet, because we're using our value semantics here 133 00:06:45,220 --> 00:06:48,190 and our pointer semantics here, think about it. 134 00:06:48,190 --> 00:06:51,640 The only thing that ever would have to be on the heap, 135 00:06:51,640 --> 00:06:53,510 if anything, and nothing here is on the heap, 136 00:06:53,510 --> 00:06:54,610 it's a literal string. 137 00:06:54,610 --> 00:06:56,580 But let's say it wasn't a literal string. 138 00:06:56,580 --> 00:06:59,450 Let's say that this string was created dynamically. 139 00:06:59,450 --> 00:07:03,000 The only thing that would have to be on the heap 140 00:07:03,000 --> 00:07:05,960 is this one thing. 141 00:07:05,960 --> 00:07:10,000 Everything else can stay on our stack. 142 00:07:10,000 --> 00:07:15,000 I wanna stress that our job is to identify and balance 143 00:07:16,130 --> 00:07:18,030 when do we use value semantics, 144 00:07:18,030 --> 00:07:20,480 when do we use pointer semantics, 145 00:07:20,480 --> 00:07:23,510 and to balance that and to try to minimize 146 00:07:23,510 --> 00:07:26,100 allocations the best we can. 147 00:07:26,100 --> 00:07:28,510 Look at how powerful the string is. 148 00:07:28,510 --> 00:07:31,460 The string value is designed to be leveraging 149 00:07:31,460 --> 00:07:34,810 value semantics, it's designed to be copied. 150 00:07:34,810 --> 00:07:36,830 When something's designed to be copied 151 00:07:36,830 --> 00:07:40,140 we have a great chance of keeping it on the stack. 152 00:07:40,140 --> 00:07:42,980 The only thing that has to allocate to the heap is this. 153 00:07:42,980 --> 00:07:45,020 What this means is is that the garbage collector 154 00:07:45,020 --> 00:07:48,940 doesn't have to deal with one, two, three, four, five 155 00:07:48,940 --> 00:07:51,730 values, it only has to deal with one. 156 00:07:51,730 --> 00:07:54,340 There's a chance that that value also maintains 157 00:07:54,340 --> 00:07:55,580 a longer lifetime. 158 00:07:55,580 --> 00:07:57,750 Do you see what we're talking about here? 159 00:07:57,750 --> 00:08:00,510 Your value and your pointer semantics are important, 160 00:08:00,510 --> 00:08:02,730 they're critical, they're critical to everything you do. 161 00:08:02,730 --> 00:08:05,760 For optimizing for correctness and performance. 162 00:08:05,760 --> 00:08:08,750 We have to continue to talk about these semantics 163 00:08:08,750 --> 00:08:11,540 as we continue to talk about code, and start to really 164 00:08:11,540 --> 00:08:15,250 appreciate the balance that we have to have and, again, 165 00:08:15,250 --> 00:08:17,150 when to use those value semantics 166 00:08:17,150 --> 00:08:18,930 and when to use those pointer semantics. 167 00:08:18,930 --> 00:08:20,140 It's critical. 168 00:08:20,140 --> 00:08:23,700 I wanna share with you the idea that these semantics 169 00:08:23,700 --> 00:08:26,360 really go deep into the language. 170 00:08:26,360 --> 00:08:29,520 This is not anything that I'm making up. 171 00:08:29,520 --> 00:08:31,660 I'm not making this up to make a point. 172 00:08:31,660 --> 00:08:32,600 These things are real. 173 00:08:32,600 --> 00:08:35,760 The value and the pointer semantics are very real. 174 00:08:35,760 --> 00:08:37,700 I wanna show you that with this particular 175 00:08:37,700 --> 00:08:38,960 piece of code right here. 176 00:08:42,008 --> 00:08:45,300 What we're gonna be able to do is predict the output 177 00:08:45,300 --> 00:08:48,910 of this code because we understand the semantics. 178 00:08:48,910 --> 00:08:52,770 Remember, mechanics is about how things work underneath. 179 00:08:52,770 --> 00:08:55,650 Semantics are about how things behave. 180 00:08:55,650 --> 00:08:58,920 Before I run any of this code, I wanna add an extra 181 00:08:58,920 --> 00:09:01,570 print line here so we can just kind of break 182 00:09:01,570 --> 00:09:03,160 the output up. 183 00:09:03,160 --> 00:09:06,540 What we're gonna start with is on line 12. 184 00:09:06,540 --> 00:09:10,880 On line 12, we're declare that array of strings again. 185 00:09:10,880 --> 00:09:11,713 Here, we do it again. 186 00:09:11,713 --> 00:09:13,590 Let's just map this out on the board. 187 00:09:13,590 --> 00:09:15,140 We kinda already have it here. 188 00:09:17,160 --> 00:09:19,440 We can reuse this no problem. 189 00:09:19,440 --> 00:09:22,880 What you notice right now is we have this array 190 00:09:22,880 --> 00:09:26,030 of friends, it's the five strings, again. 191 00:09:26,030 --> 00:09:29,080 The first one there is gonna be Annie, I'll just put A. 192 00:09:29,080 --> 00:09:32,650 The next one over there is Betty, and then we've got 193 00:09:32,650 --> 00:09:36,050 Charles, you see that, and those integers are gonna 194 00:09:36,050 --> 00:09:39,870 be five, five, six, so five, five, six. 195 00:09:39,870 --> 00:09:40,703 No big deal. 196 00:09:40,703 --> 00:09:41,536 You're getting a sense of that. 197 00:09:41,536 --> 00:09:44,850 What's important right now is this. 198 00:09:44,850 --> 00:09:47,050 Look at what I do on line 13. 199 00:09:47,050 --> 00:09:51,400 On line 13 I say display the string in index one, 200 00:09:51,400 --> 00:09:54,710 which is Betty, so we should see Betty 201 00:09:54,710 --> 00:09:56,470 when we run the program. 202 00:09:56,470 --> 00:09:57,620 There it is. 203 00:09:57,620 --> 00:09:59,100 Now, let's go into the four. 204 00:09:59,940 --> 00:10:02,860 What you're seeing for the first time is what I would call 205 00:10:02,860 --> 00:10:07,190 the value semantics form of the four range. 206 00:10:07,190 --> 00:10:10,050 This time, all we're asking for is the index 207 00:10:10,050 --> 00:10:12,080 position on every iteration. 208 00:10:12,080 --> 00:10:16,090 Remember before, we were using the value semantics. 209 00:10:16,090 --> 00:10:18,260 We're asking for the index position and a copy. 210 00:10:18,260 --> 00:10:19,590 What does value semantics mean? 211 00:10:19,590 --> 00:10:21,886 We're always operating on our own copy. 212 00:10:21,886 --> 00:10:26,110 This is the pointer semantic form of the four range. 213 00:10:26,110 --> 00:10:28,940 On the very first iteration of this loop, 214 00:10:28,940 --> 00:10:32,520 we change out Betty to be Jack. 215 00:10:32,520 --> 00:10:33,860 We change this out. 216 00:10:33,860 --> 00:10:36,370 This now says Jack. 217 00:10:36,370 --> 00:10:37,840 Great. 218 00:10:37,840 --> 00:10:40,080 Then, we iterate again. 219 00:10:40,080 --> 00:10:41,540 We get to index one. 220 00:10:41,540 --> 00:10:43,390 We replace Jack with Jack again. 221 00:10:43,390 --> 00:10:44,540 It's very inefficient. 222 00:10:44,540 --> 00:10:45,980 It's not the point of the algorithm. 223 00:10:45,980 --> 00:10:49,170 What's the point is that on line 18, once we're iterating 224 00:10:49,170 --> 00:10:52,660 over one, I ask to display the value at index one. 225 00:10:53,610 --> 00:10:55,310 We should see Jack. 226 00:10:56,180 --> 00:10:58,600 If I were to run this program, we would see 227 00:10:58,600 --> 00:11:02,450 in the output Betty and Jack. 228 00:11:02,450 --> 00:11:03,700 Not surprising. 229 00:11:03,700 --> 00:11:05,470 Exactly what we would expect. 230 00:11:07,195 --> 00:11:09,980 Let's take the same algorithm, the same piece of code, 231 00:11:09,980 --> 00:11:14,980 but this time let's use the value semantic form 232 00:11:15,290 --> 00:11:17,160 of the four range. 233 00:11:17,160 --> 00:11:19,290 We start up all over again. 234 00:11:19,290 --> 00:11:23,960 We've got Annie, we've got Betty, we've got Charles, 235 00:11:23,960 --> 00:11:26,710 we keep going, and I display the string 236 00:11:26,710 --> 00:11:29,000 at index one again, which should be Betty. 237 00:11:30,280 --> 00:11:33,550 The one thing that we've changed in this code is we're now 238 00:11:33,550 --> 00:11:38,070 using the value semantic form of the four range. 239 00:11:38,070 --> 00:11:41,610 Notice again, I go in, and on the first iteration 240 00:11:41,610 --> 00:11:44,170 I change Betty to Jack. 241 00:11:44,170 --> 00:11:45,370 No big deal. 242 00:11:45,370 --> 00:11:47,090 We change it again. 243 00:11:47,090 --> 00:11:48,830 Everything looks the same. 244 00:11:48,830 --> 00:11:53,310 We do it a second time, and on the second time we print V. 245 00:11:53,310 --> 00:11:56,130 We would assume that V would also be Jack, 246 00:11:56,130 --> 00:11:58,390 because we changed it out before 247 00:11:58,390 --> 00:12:01,680 we got to the second iteration. 248 00:12:01,680 --> 00:12:03,080 Notice the output. 249 00:12:03,080 --> 00:12:07,710 It still says Betty, and then it says Betty again. 250 00:12:07,710 --> 00:12:09,370 What is going on? 251 00:12:10,600 --> 00:12:11,950 Understand this. 252 00:12:11,950 --> 00:12:14,540 Value semantic mean that we're operating 253 00:12:14,540 --> 00:12:16,170 on our own copy of the data. 254 00:12:16,170 --> 00:12:19,920 When I say this four range is using value semantics, 255 00:12:19,920 --> 00:12:24,697 what it means is the four range in this form makes a copy 256 00:12:25,980 --> 00:12:28,230 of the array it's iterating over. 257 00:12:28,230 --> 00:12:32,170 It's not iterating over this array friends. 258 00:12:32,170 --> 00:12:37,170 Before the iteration started, it made its own copy of this. 259 00:12:38,930 --> 00:12:41,250 It made its own copy. 260 00:12:41,250 --> 00:12:46,250 Which means that it's pointing to its own Betty and Charles. 261 00:12:46,460 --> 00:12:49,370 We're not iterating over this, we're iterating over 262 00:12:49,370 --> 00:12:51,340 the copy of this. 263 00:12:51,340 --> 00:12:54,000 That's what value semantics are all about. 264 00:12:54,000 --> 00:12:55,510 That is the behavior. 265 00:12:55,510 --> 00:12:57,820 I've told you over and over again, if you don't understand 266 00:12:57,820 --> 00:13:00,000 your mechanics, and more importantly don't understand 267 00:13:00,000 --> 00:13:03,580 your semantics or your behavior, you cannot predict 268 00:13:03,580 --> 00:13:06,260 how this code's gonna run and therefore the impact 269 00:13:06,260 --> 00:13:07,930 that it's going to have. 270 00:13:07,930 --> 00:13:09,130 Very, very interesting. 271 00:13:09,970 --> 00:13:12,850 It's gonna be important to choose the right form of the four 272 00:13:12,850 --> 00:13:15,750 range based on the data that you're operating on. 273 00:13:15,750 --> 00:13:18,300 What we're gonna learn at some point is the data 274 00:13:18,300 --> 00:13:21,570 drives the semantic, and whatever semantic we're supposed 275 00:13:21,570 --> 00:13:23,450 to use for the data, we have to be consistent 276 00:13:23,450 --> 00:13:25,170 and clean throughout our code base. 277 00:13:25,170 --> 00:13:27,700 We're gonna continue to see this over and over again. 278 00:13:27,700 --> 00:13:30,910 Let me show you something that I never wanna see in code. 279 00:13:30,910 --> 00:13:33,540 I've tried to tell ya several times that if you 280 00:13:33,540 --> 00:13:37,840 mix semantics, code becomes complicated and hard to read. 281 00:13:37,840 --> 00:13:39,480 Look at this code here. 282 00:13:39,480 --> 00:13:43,200 We're using the array of five strings, there it is, 283 00:13:43,200 --> 00:13:47,430 we display Betty like we did before, no change. 284 00:13:47,430 --> 00:13:52,420 But look, I am going back and using the value semantic 285 00:13:52,420 --> 00:13:54,550 form of the four range. 286 00:13:54,550 --> 00:13:58,280 However, I'm not making a copy of the array, 287 00:13:58,280 --> 00:14:03,280 like I did before, this time the value semantic form 288 00:14:03,320 --> 00:14:08,320 of the four range is making a copy of the array's address. 289 00:14:11,750 --> 00:14:14,260 That means that when we iterate on this four range 290 00:14:14,260 --> 00:14:16,830 using value semantics, we're actually doing it 291 00:14:16,830 --> 00:14:19,350 over pointer semantics, which means that when 292 00:14:19,350 --> 00:14:23,340 we update friends we're updating it indirectly 293 00:14:23,340 --> 00:14:25,490 through the pointer, and we still see Jack. 294 00:14:26,360 --> 00:14:31,090 This code is so nasty and confusing it just makes me sick. 295 00:14:31,090 --> 00:14:34,500 We cannot be mixing semantics like this. 296 00:14:34,500 --> 00:14:37,610 This is when code gets ugly, it gets confusing, 297 00:14:37,610 --> 00:14:40,750 it gets impossible to read and impossible to predict. 298 00:14:40,750 --> 00:14:44,160 I'm gonna be stressing over and over and over again 299 00:14:44,160 --> 00:14:48,460 that we do not want to be mixing semantics. 300 00:14:48,460 --> 00:14:50,650 We're gonna look at our data, we're gonna understand 301 00:14:50,650 --> 00:14:53,370 our data, we're gonna choose our data semantic, 302 00:14:53,370 --> 00:14:55,940 and then all of the code we write will follow 303 00:14:55,940 --> 00:14:59,770 and respect the semantic, not the other way around. 304 00:14:59,770 --> 00:15:03,100 For those of you who might be a little new to arrays, 305 00:15:03,100 --> 00:15:05,900 remember that we said that the array provides 306 00:15:05,900 --> 00:15:08,580 that contiguous block of memory. 307 00:15:08,580 --> 00:15:10,460 Look at this code here. 308 00:15:10,460 --> 00:15:12,920 I've got that same array of five friends. 309 00:15:12,920 --> 00:15:15,810 We're gonna range using our value semantics, 310 00:15:15,810 --> 00:15:17,980 but what I'm gonna do is ask for the address 311 00:15:17,980 --> 00:15:21,570 right here at the end of every single element 312 00:15:21,570 --> 00:15:23,450 and what that is in memory. 313 00:15:23,450 --> 00:15:28,450 What you're gonna see is when we display the addresses here, 314 00:15:28,610 --> 00:15:33,610 you'll see that we're at 150, 158, 160, 168. 315 00:15:35,490 --> 00:15:37,260 You're gonna see two things in this output. 316 00:15:37,260 --> 00:15:41,750 One, every one of these elements are next to each other. 317 00:15:41,750 --> 00:15:44,140 They are on a contiguous block of memory. 318 00:15:44,140 --> 00:15:47,220 The other thing you're gonna see is the predictable stride. 319 00:15:47,220 --> 00:15:50,220 Remember, a string on the playground is eight bytes. 320 00:15:50,220 --> 00:15:53,890 Two words, every word is four, four plus four is eight. 321 00:15:53,890 --> 00:15:58,890 What you're seeing is an eight byte step through the array. 322 00:15:59,270 --> 00:16:01,820 That is our predictable stride. 323 00:16:01,820 --> 00:16:02,900 Eight bytes. 324 00:16:02,900 --> 00:16:04,420 You can see it on the address. 325 00:16:04,420 --> 00:16:07,230 We also talked before, remember, about alignments 326 00:16:07,230 --> 00:16:09,900 so we shouldn't be confused that an eight byte value 327 00:16:09,900 --> 00:16:12,310 falls on a zero eight byte alignment. 328 00:16:12,310 --> 00:16:15,840 Everything that we've talked about is coming together, 329 00:16:15,840 --> 00:16:18,140 but what's important, again, here is that we do 330 00:16:18,140 --> 00:16:19,880 have a contiguous block of memory. 331 00:16:19,880 --> 00:16:21,980 We see those addresses are next to each other. 332 00:16:21,980 --> 00:16:23,510 We see the predictable stride. 333 00:16:24,520 --> 00:16:27,570 Again, the hardware loves this because the prefetchers 334 00:16:27,570 --> 00:16:31,300 are gonna be able to come in and make those great 335 00:16:31,300 --> 00:16:34,490 predictions over the cache lines that this data's on 336 00:16:34,490 --> 00:16:37,090 and we should get some better performance 337 00:16:37,090 --> 00:16:39,610 because it's about how efficiently we get data 338 00:16:39,610 --> 00:16:42,520 into the processor, not how fast we pump it.