So we are going to go into details of how to make a Haskell program more performant. So how many of you think that Haskell must be slower than C? Okay, one. All right. So it must be slower than C. So we'll see that Haskell can do as well at C with some effort. Right? And we'll see what kind of roadblocks are there. So let me introduce myself. I'm Harind. I have, for the good part of my life, I have worked on C. And for the last few years I have been programming in Haskell. And I'm trying to, currently I'm focusing on Streamly, a library that aims to unify several aspects of Haskell programming into a very simple list, uniform list API. Particularly it makes concurrent and non-concurrent programming indistinguishable. So but today we'll talk about performance. So let's see. So this is a high performance library and this is the context in which I started looking at how to make Haskell better perform better. And what are the problems? What are the roadblocks? What are the problems? It's based out of that and one other library that I'll talk about shortly. So there are a lot of slides. So I'll try to breeze through some of them so you can go and look at more details later on in the slides. So in Haskell performance can easily drop by 10x or 100x very easily. Just one change and it's just 100x slower. In C refactoring is a nightmare for correctness but performance is more or less unaffected. But in Haskell it's the opposite. Correctness can be guaranteed. Refactoring is very easy. Correctness will be there. But performance will get affected and you'll have to do some work to get back to the same performance. So you cannot be confident unless you measure. So that's what I have figured from my experience that you have to measure everything to be sure it forms well. So best practices can get you in the ballpark but squeezing the last drop of performance can be harder. It could be an art for the Renaissance. People need to know about the specific details. But with some effort you can get to see. So let's take a look at a case study. I wrote a library called Unicode Transforms in response to an issue in the Haskell build tool stack. This library, so I think all Haskellers in their lifetime many of them they try to prove that Haskell can form as well as C. I have seen many of this series but this one is not a toy program. This is a real life useful library. And I compared it to an ICU international consortium for Unicode ICU library which does Unicode normalization. And compared this library with that to see whether it can perform as well as the best library available in C++ land. So what's the problem that we are trying to solve in this library? The Unicode characters may have multiple forms. They could be composed or decomposed. So a composed character as you can see in the first lines of the green characters they are composed characters. So they have for example the A with an adornment. It is 00C5 and then O with an adornment it's 00F6 and then they decompose into these codes that are written in orange. So how do you compare strings? They could be in different forms. How would you compare them? So you have to bring the string into a normalized form before you can actually compare and say these two strings are equal. So you have a sequence of characters. So when you decompose a composed character into multiple characters, so you will have a starter and there are combining characters followed by the starter. And the combining characters they need to be put in a certain order because if the order is different then your result will be different. You can't compare deterministically. So you need to have the combining characters reordered in the standard form. So to do that what do we need? So we have a couple of lookup maps. There is a decomposition map where you want to know given this character how which characters does it decompose into. There is a combining class map which says what order the combining characters should be in. And then there are Hangul characters which are called the Chinese, Japanese and Korean. So they are in tens of thousands not hundreds. And so there is an algorithmic decomposition for those characters compared to the other characters which have mappings. So there was this library written by Antonio Nikishov. So this was around 50 lines of code for normalization. It used map for database lookup, lookup of characters and Haskell lists for processing. This was idiomatic code. In just 50 lines you could do whole normalization very elegant code. So this is the performance of that code. So ICU, first one is the ICU and the second one is the beautiful elegant Haskell code. So it is close to 200 millisecond the Haskell code and the ICU library performs less than 10 millisecond. So 20 times worse and in the worst case it is maybe like some 70, 80 times worse. For English ICU takes close to 2.7 milliseconds. So instead of int maps, so the first change that I tried was like this is a read-only database, right? So why don't you use the GSC pattern match lookup instead of using the int map? So I looked at the GSC code and saw that the GSC folks have done a really good job in making the pattern matching very efficient. So the code looks like this, pattern matches, so you have all the characters that is automatically generated from the Unicode database, this code. So let's see how it performs. So on the left you see the improvement. It's negative, so that means improvement. So this much is the improvement compared to what it was before. On the right is the absolute values and on the left is how much improvement you got with this pattern match. But this is not much. Then I tried the path path decomposition lookup. I mean instead of looking up the actual decomposition of a character, first lookup whether it is decomposable or not. A lot of characters are not even decomposable, right? So you would use a bitmap to see whether it is decomposable. If it is decomposable then you go to the secondary lookup saying, okay, what is the decomposition? So that didn't have much impact. It had some improvement in two cases. So let's try something more. So decomposition is recursive. If a character decomposes into two code points, then they can further decompose into more and the process keeps going on. It will terminate at some point, right? So instead of using iterate, zip and tail more idiomatic code, just use a simple recursion to do that. So that gave some improvement. Now for reordering, the code was splitting it into groups, right? And then you sort by a combining class to reorder them, right? So this is like, there is a starter, then combining character, then another combining character. So we have split the list into multiple lists, right? For each group. So whenever a new starter, starters are characters with combining class 0. So if you find that there is a combining class 0, then you start a new group, right? So and then these groups, you use the regular sort to sort it, right? So the optimized code, it uses custom sorting for the cases when the group size is one or two. So in most cases, you will find that there is only one or two combining characters in the first part. So if you optimize that case, you would have optimized quite a bit, right? Because the other cases are slow path. I mean, you will rarely encounter more than three, four, or as the number starts increasing, there will be rarely, you will see rarely those kind of decompositions, right? So then use a bitmap for a quick combining or non-combining check. I mean, instead of getting the combining class directly, because a lot of characters are not combining. So in the most cases, you will find that it is not combining.  Then the next optimization was, so original code had reorder.decompose, right? It's modular. There are two stages. You're decomposing, then you're reordering, right? So instead, we made it monolithic. So it's not as elegant as before, but it performs better. So we said, okay, decompose and reorder and use a reorder buffer to actually reorder during decompose itself. So in the common case, the buffer will have just one character and it will get flustered as soon as we get the next character because the next character is not combining, right? So we only need to sort the buffer only when there are more than one combining characters and we use custom sorting for two characters. We just swap them if needed, right? So another problem was that I was using string append, which was not performing too well. So instead, manually deconstruct the list and reconstruct for short strings common cases. So that gave 10% improvement. For the CJK characters, the Chinese, Japanese and Korean, it's called Hangul characters, right? So Hangul Jamu. So Unicode specifies a algorithmic way to normalize that, right? So there are multiple small changes which made it much better. So we use the algorithmic decomposition plus. So Hangul Jamu case is more expensive compared to the regular fast path case. So we know inline it so that it doesn't impact the fast path. Then use code and REM instead of div and mod. So that gave some improvement. Now instead of using code and REM, use code REM, right? In one operation, you will get both quotient and remainder, right? Then instead of using care, use unsafe care. So that doesn't do a check of legality of the code point, which we already do somewhere else. And use strict values in list buffers instead of using lazy lists. So make them strict. Then the next was like instead of using lists, for short buffers, use tuples. That performed even better. And another change was like localizing recursion. Instead of having a big recursion loop, localized recursion to wherever it is needed, only to that point don't recurs over a big code. So with all these optimizations, what we got was this. So the first one is ICU. The second one is after optimization, Unicode transforms. The third one is C code, which is another implementation of normalization, UTF-8 proc. It is written in C. So Haskell is doing better than that, but it is still not as good as the best implementation in C++, which is the ICU implementation, right? So can we do better? So we are still using plain Haskell strings. So I did some small experiments to see, like in the limit case, how are we performing? Let's say we map care plus one to a string and to text. So using the text library. So the string performed 17 milliseconds, and text was 11 milliseconds. So slightly better, right? Then ICU, if I use text just stream and unstream, right? Instead of doing a mapping on it, it takes four milliseconds. That's the minimal operation that you can do on text, right? And ICU normalization itself, the whole full normalization is taking 2.7 milliseconds, so we have no chance, right? Just streaming and unstreaming is taking much more than that. So then I looked at what is going on in the unstream and stream code. So I separated some of the memory reallocation code and did a knowing line on that to move it out of the fast path, right? And that made us to 1.3 millisecond unstream and stream, right? And now we have a chance. I mean, we can compete with the ICU normalization using the text library. So let's apply that now. So we use text with stream and unstream instead of using strings. Then there was some conditional just branch readjustments like some fast path branches. It can give you some sort of improvement even by rearranging code, have the fast path branches arranged in such a way that they're more efficient, right? Then just one inlining gave 16% more and no inlining slow path code gave some improvement and using the unbox strict fields gave some more improvement. So with these small changes and optimizing the reorder buffer now, so instead of using a list, use a custom data type. So we use a buffer type with empty one character and many characters. So one character case is unpacked. So this is optimizing the fast path again. I mean, that's the common case. So use the most efficient data structure for that, right? And use a mutable reorder buffer instead of using a list. We used a array, a mutable array. So this gave us like plus 5%, but at that point, that 5% was a really good improvement because we had already optimized quite a bit. So where are we now? After this, what we got is pretty close to ICU, right? In the Korean characters case, the Korean benchmark, we are actually doing much better than ICU, right? And in most cases, it is slightly worse in other cases, but quite there in the wallpark, very close to C. But now let's use LLVM as the back end.  So it generates better code in some cases. So that gave it 10% boost by just using the LLVM backend. And we are pretty close to C now, right? And we can do even better. There are more algorithmic optimizations that we can do. And the ICU library also uses the QuickCheck properties, not the QuickCheck in Haskell, but the Unicode specifies some QuickCheck properties. Using that, you can quickly figure out whether you need to normalize or not normalize, right? So that library has that advantage as well, right? Even then, we are pretty close, right? We are not using QuickCheck properties in our algorithm. Code generation by GHC can possibly be improved. I raised a couple of tickets when I was investigating this. The code generation is not... The registry allocation in some cases is not great. Perhaps can be improved, and the memory allocation can also be improved a little bit in one case. So what are the lessons? What are the learnings from this? So we can write concise code in Haskell pretty quickly. It may not perform so well. The code can be optimized to perform close to C. Most of the optimizations that we did were not like language features or language-related stuff. We did... Mostly, we did like fast path optimization, right? How to do better, use better data structures for the fast path, right? The most common language-related optimizations that we did was inlining, right? Figure out where to put an inline. So I usually say that half the time you take in writing the code and half the time you take in figuring out where to put an inline. So, yeah, so that's the most common optimization that we did other than strictness from where we are here or there, right? Yeah, we can do as well as C. So if you think Haskell can't do as well as C, so this is an example. And this is a library which is not a toy. It's being used by Pandoc, for example. I recently looked at it, so Pandoc is using this library now. So let's take a look at the ground rules for optimization. So in Haskell, I say in Haskell you need benchmarks and C you need tests, right? So Haskell is like pretty sensitive to benchmarking, and that's the only thing, one thing that in my experience that is fragile is inlining. So if you can figure out what to inline, then you're good. So if GSC can do it better, then perhaps this problem will go away. So the ground rules are measure, analyze, optimize, so algorithmic optimization first. So most of the time we think this is performing slow. It might be because your logic is not good. I mean, it's not according to the best possible optimized way. Do we just gain first and optimize where it matters? That's the most important. I mean, optimize the fast path. Why would you optimize something which is not even coming in the fast path? It happens once in a while. That's what we did in the Unicode Normalization Library. We optimized for the cases which occurred most frequently. Now debugging, so from my experience, so it helps to narrow down incrementally. So if your code is not performing well and you made some changes incrementally to the code, now you start figuring out, okay, remove this, remove this, remove this, what is, where is the culprit, right? And that helps quite a lot. Same way you can do incremental addition or incremental elimination. Both techniques you can use to figure out where is the problem. And then ratchet. So we discover one issue in, like, one day I spent discovering something, and if during refactoring I may lose it, right? Let's say I remove the inline or something happened during the refactoring. So you will again spend the same time, so you do ratcheting. So you never let your code to perform worse than what it was before, right? Just at least as much, as good as it was before. So the three things that you need for optimization in Haskell is inlining, specialization, and strictify your data structures where needed. So if you take care of these three, then you're good. For, like, almost more than 90% cases, or even I'll say 99%, you won't need much more unless you are, like, hungry for the last drop performance. Or some corner case, you ran into some corner case for which you may need some weird kind of optimization, right? Let's talk about inlining. So what is inlining? Just instead of making a function call, you expand the definition of a function at the call side, right? Very simple. Now, there's a big confusion when you're beginning to write Haskell code. There's a confusion, like, because the inlining process is distributed at two places, at the call side, at the definition side. So there are things that you can do at two places which can help or block inlining. So for a function to be able to inline, you need its definition in the interface file. And for it to be in the interface file, there are many ways it could land up in interface file. One is, like, GSC decides, okay, this can be inlined. It's a short function. So it will put it there. The other way is you put an inline on it. So the compiler will definitely put it in the interface file because it has to be inlined. If you put an inlineable, then that is also a directive to say, okay, put it in the interface file, right? Inline is like inlineable plus also inline it at all call sites, right? So that's a directive to say, put it in the interface file plus wherever it is used, inline it, right? So at the call site, the prerequisite is that the function must be in the interface file. It must be available. The definition must be available in the interface file. So you have to do, ensure that it is in the interface file if you want to ensure that it will be inlined, right? Either use inline or inlineable. So if it is marked inline, so it will be inlined everywhere, right? It will be there in the interface file as well. But if it is marked inlineable, you can inline it using the inline call as well. So there is a function called inline which is in DHC, DHC prim, right? The primitive package. So you can use that as well if the function was not marked inline at the definition site. So you can decide at the call site. So that way you can say inline here but don't inline here, right? With inline it will be inlined everywhere. So when inlining cannot occur, so we need to understand that to be able to understand, okay, we might get confused if this is not getting inlined. So what happened? So the function has to be fully applied. If it is partially applied, it cannot be inlined, right? If the function is passed as an argument to another function which is not inlined, then again it won't be inlined, right? That's one of the reasons why it can't be inlined. If the function itself recursive, there is no point inlining, right? In mutually recursive functions, DHC tries to use, tries not to use a function with an inline pragma as a loop breaker. So in mutually recursive, you have to use one of the function as a loop breaker because of loop, right? So what happens when an inline is missing? So look at this code. So this is one of the benchmark codes in Streamly package. So there was no inline on this function. So I figured that without an inline, it was taking 50 milliseconds. With an inline, 500 microseconds, right? That's 100x faster. So just one missing inline can cause, like, your program is performing so much slower. So what is happening here? Without marking the function funk inline, the f, which is an argument to it, it cannot be inlined and therefore it cannot fuse with mapM there. So the stream fusion can really get you very tight code which performs really well. But if it doesn't happen, then it will be a function call and which will be very slow, right? So in this case, that's what was happening. So one point to note here is that fusion is very sensitive to inlining, but CPS code, the continuation passing style code, is not, it's pretty robust. So in Streamly, I have both versions. All combinators are available in CPS as well as in direct fusion style. And we use what makes sense at a particular point. So CPS has been very robust though it is very slow compared to the fusion code, but it is very robust against inlining. In fact, the fusion code can perform much worse than CPS if there is an inline missing, right? So it's not like CPS is, because CPS is slow in itself. So that's why it is slow. So that's why it is robust for inlining because it doesn't matter, right? So this is counterintuitive for many people. DSC manual also says that you won't need no inline anywhere, but I use no inline all the time and it helps in performance because you push the slow path code out of the way and let the fast path code work better. So the way CPS works, right, when you fetch the instruction pipeline, so if a lot of junk gets in the middle, it won't be as efficient, right? So if you do no inline, okay, put it in a separate function, market no inline, it's out of the way. Okay, this case happens once in a while, just put it out of the way. Let my fast path code be as efficient as possible. Now the specializes another technique. It's not required as often as inline, but this is one of the important ways of polymorphic code. So inlining copies the function at the call site, right? Specializing, it makes a copy which is specialized to a particular type. For a polymorphic code, you can make multiple copies for different types, right? So that way you can have more efficient as if you wrote one homomorphic code, not polymorphic, right? So this is one example of specializing. So let's move on. I think we don't have much time. So you need inlineable for a specialized issue. So you need to mark a function at definition site inlineable because you need to understand that to be able to specialize in a different module, the function definition has to be available in the interface file. So inlineable does that, so you can specialize it in a different module in a specialized directive tagma there, right? So this is confusing initially because inlineable, what does it have to do with the specialization, right? One may think like that, but its meaning is overloaded. What it does is put the definition in the interface file. If you understand that, then you will understand, okay, it can be used for specialization or it can be used for inlining in a different module. So at the call site, then you can use the specialized directive. Once you have ensured that it is there in the interface file, you have used inlineable or inline on it. That will make sure it is there. So then you can use specialize in a different module. Now another important optimization is call pattern specialization, which I actually used in encode transforms library. So with this, what you can do is that you can think about it as if there are different constructors of a data structure, right? And there is a recursive function which uses that data structure as an argument, right? So that recursive function can be specialized for each constructor of that data structure. For each constructor, I think you have a separate copy of that function, right? So that way for each constructor, it can be made more efficient. So and you can force it by using a special argument called spec. You can force the function to use constructor specialization and that's heavily used in vector and streamly as well. For recursive functions, you have different constructors. For each constructor, you may want to specialize it to just use spec constructor. So when specialization cannot occur, the function is not fully applied, it can't occur. The function calls for the functions which cannot be specialized, then you can't specialize that function itself. If the function uses polymorphic recursion, you can't specialize it. So the third technique is strictifying. So I have written buffers here because it's usually used when you are buffering data. That's when it is required. When you're processing data, you use streaming. When you are buffering data, then you need buffers which should not be taking up so much space, they should be reduced most of the time. So you don't want to keep lazy expressions which are anyway ultimately going to be reduced so that puts pressure on GC. So as a general rule, be lazy for construction and transformation and be strict for reduction. When you have to reduce strict, use everything strict. When you are doing a folder, for example, that's transformation, so use lazy structures. When you are constructing new structures, be lazy. And in left-folds, it's reduction, so use strict accumulator. That helps a lot in certain cases. And use strict record fields. Unbox is another technique, so you can use the unpack-pagma to have the constructor fields unboxed. So wherever you think it's a buffering data structure, you are using it like a buffer. So strictify it, unbox it if possible. So that will help. Unbox may not help in all cases because if you are using it again and then the compiler has to re-box it, then it won't be as effective. But if you are just keeping it there as a buffer, unboxing will help. All right, we have 10 minutes. Let's come to measurement. So benchmarking. So how do you do benchmarking? So there are two tools, Gaze and Triterion. Triterion is the go-to tool, right? Which actually benchmarking in Haskell started with Triterion, kind of, right? That's the gold standard for benchmarking. But the new tool created by Vincent Hanke is Gaze. He removed a lot of dependencies from Triterion and was fast-moving, so I contributed quite a bit to Gaze. Instead of Triterion, it builds faster as well. So we faced several benchmarking issues during extremely development and made significant improvements to Gaze to address those issues and also wrote the bench show package to be able to scale analyzing benchmarks. So what are the pitfalls in benchmarking? So the code needs to be... The benchmarking code needs to be optimized exactly the same way as you would optimize your regular code, right? Otherwise, your benchmarks will be invalid. You haven't... So we saw that there was a missing inline and it caused the benchmark to run very slow. So your benchmarking code has to be fast, right? In one case, I found that the RNF implementation of a particular data structure was slow in itself. So benchmarking code uses the NF data instance to reduce the data structure deeply, right? That's how it works. So if the implementation of reduction itself is not fast, then it will look like it is very slow, but actually the code is not slow. Its measurement is slow. The NF data instance is slow. So the other critical problem was that multiple benchmarks can interfere with each other. In one case, I saw that the benchmark that was listed later in the list of benchmarks performed much slower. So I was comparing, for example, the multiple streaming libraries and the streaming library which was at the end was the worst. So the problem was sharing. So what we did was that run each benchmark in a separate process. So start from scratch for each benchmark, right? So that's what I introduced in Gage. So Gage can do that. You can run each benchmark in a separate process. So you could be doing nothing even with NFIO. If you are using NFIO, so the NF in benchmarking, when you use NF, normal form, right? Application in pure case, you use a function application. But in IO case, you don't use function application. But in many cases, it may be the pure component of the IO thing that you are measuring which may be taking a lot of time. And then you do NFIO, it doesn't do anything. It's just nanoseconds. It's coming out to be nanoseconds where it should be milliseconds or microseconds, right? So there was one improvement in Gage to address that as well. It's there in criterion as well. So we run each benchmark in isolation. So in Gage, other things that were added was like measuring all the getR uses stats, which includes RSS, page faults, context switches. So you can gather all that information using Gage. And there is a quick mode that I added. So you can measure in less than a second instead of waiting for a lot of time to run. If you're running so many benchmarks, you don't want to run for that long, like waiting for minutes to put the benchmarks to finish. Even though the difference in the measurement is not that much. All right, so let's move on to bench show. So in Haskell, benchmarking is a business. You could... I don't want to miss... I don't want to say that, okay, this inline is missed, this function got 100x slower, right? I always want to measure all the operations, all the combinators in a streamlink. So there are hundreds of benchmarks. Each combinator has a benchmark, right? So now if you have that kind of benchmarks, how do you analyze, I mean, how would you know when you run these hundreds of benchmarks, right? How would you know which one regressed? So how would you know how much regression was there, which one? So you will have to go through pages and pages of the output and see, okay, this one was this much and now it got this much. How do you do that? So bench show solves that problem. And for stable comparison, it uses three statistical estimators, linear regression, median and mean. And we try to get the best out of three, right? Which one gives you the minimum difference? So that's what we use. You may use whatever you want, but that's what by default I use using bench show. And then it computes the percentage regression or improvement because different benchmarks, they may be... So one benchmark regressed by 45 milliseconds, right? The other benchmark regressed by, let's say, 45 microseconds. But both of them may have regressed by 5% or 2%, right? So you can't, by absolute values, you can't figure out, okay, which one I have to focus on to improve, right? So the one which regressed by 50% may be the one that I need to focus on, rather than the one which regressed by 45 millisecond, right? So we compute the percentage difference and then sort it by the percentage difference which one regressed most, right? And then I have a list of, like, what I need to attack, right? I need to attack the first one in the list, first, right? That's the benchmark that regressed most. And we can automatically report regressions on each comment using this, right? And it uses a threshold as well. You can configure, okay, if benchmark regressed by more than 5%, then only then report, right? Or you can say, fail if something regressed by more than 5%, right? So this is one of the outputs, like, percentage difference. You can see it is sorted. The first one regressed by 596% and then it keeps going down, right? So you can also visually see the graphs. So you can see here the same thing visually. The second graph, it shows the delta from the first graph, like how much it regressed, not the absolute comparison. The second one is the delta from the first one. So you can see the negative as well, which is improvement, actually, to some of the benchmarks, right? So how do you compare packages? So with Bench Show, you can group benchmarks arbitrarily in different groups and you can compare those groups with each other, right? You can say this one is, these benchmarks are for conduit, these benchmarks are for pipes, and then you can compare the two sets of benchmarks, right? They might be there in the same file, in the same benchmarking suite, but you can group them in different groups and then compare those groups. So this is one of the results of Bench Show, comparing Streamly, which is the first one, and the streaming library, conduit, and pipes. So the benchmarks are in the same file, right? So we grouped, okay, these are for conduit, these are for streaming, these are for pipes, these are for Streamly, and then we compared that. So it is very flexible. You can do whatever you want, whatever you can imagine it can do. So you can see I was talking about the high performance so Streamly is a focused on very high performance, so you can see that the bars are so slow you can't even see them. They're so low, I mean. Okay, so pure streaming, so this is the time comparison, so using Bench Show, so I have a package called Streaming Benchmarks, which actually compares all the streaming libraries as well as pure streaming, so which is like lists and vector. And Streamly also has a pure, a module which can do the same thing as lists do, right, the pure version. And the first one is Streamly, the second one is the Haskell standard lists, and third one is vector. You can see vector is not performing even as well as list in these cases, perhaps because it does a lot of memory allocations. This is a million elements. You're going to a million elements and doing filter, drop, et cetera. These are filtering operations. So there are more that are available in the Streaming Benchmarks package. You can see elimination operations, all kind of operations you can compare different libraries. You can even compare byte string and text to see where they stand. I didn't have a fair comparison, so I didn't include them yet. So this is the space utilization. This is what we saw in time. So vector is using 60 MB in many cases, whereas the pure stream and list, they are taking a lower amount of space. So don't think that vector is bad. Actually, Streamly uses the same code as vector, but there may be some improvements that can be done for vector. And also, you need to keep in mind that these are operations that are streaming operations and vector can do more operations which are commutable operations, right? For array operations, where lists and streams may not work well. All right, we are at the end. So here are some links you can go through them and you can send me an email or there is my Twitter handle as well. So you can contact me through these means. My email id is there on my GitHub account as well. So I also need feedback on, for example, benchmarks. Tell me what is wrong with them. I mean, if there is anything wrong, am I measuring things fairly or this is just something that doesn't make sense? My questions. So by doing all these changes to the source code, obviously it will not be idiomatic, it has to be anymore once you start optimizing a lot more. How far do you drift apart? Yeah, so I had a point about that because I breezed through it. So it was something like 50 lines of code doing all of normalization initially. It became, if I measure totally the lines in the file, it became like 500 lines, but that also includes some fundamental operations like streaming and un-streaming. If I remove that code, and I am also using like I haven't optimized composition, decomposition is very well optimized, and I can actually, perhaps, both of them can reuse the same code. If I do that, it can be compacted quite a bit. So probably I didn't know about vector at that time, so I could have used vector as well for mutable operations, right? So I may not have to use the stream-on-stream code from text. So with that, it could still be idiomatic, right? And yeah, so you need to actually to address the fast-part code, you actually need to drift from that. You can't do everything in the same way. So if you want high performance, but it is not worse than C. I mean the ICUC++ library it is used. And even if you cut out the part which is used for normalization, because that library does a lot more things, that part is quite a bit longer than the Haskell code, much longer. This could be like, I mean, 100 lines perhaps. Hi. So my question was how do you decide which functions to inline and not inline? So yeah, always measure. That's what I said benchmarking is a business. So you measure the function and if it is fast you inline it? Is that how it works? I don't understand, but how would measuring tell which parts to inline? Usually you get, so in my case, I had comparisons, right? So there are other streaming libraries which I'm comparing against and there is the vector library. So they are already optimized, so I have a baseline. It can go as much faster, why is it not going as fast? But in many cases you can also see this is not acceptable, right? In many cases it can actually go faster. So based on my understanding of the code it can't be that slow. Why is it that slow? So based on that I can sense there is something missing. I need to do better. So it might perhaps be some inlining that's missing. That means that you would have to understand the code really well and that probably works only for experienced folks. Yes you have to understand the code, but if you know that you want to get there, I mean it is not as good as it is not acceptable. So usually even the idiomatic code could be acceptable. Why would you optimize if you don't need it? If you need it then you will go and look. So generally you would run a profiler and then you would look at profiling results and then decide something. Yeah so there is profiler as well. But you did not talk about profiling at all. Yeah I didn't talk about that. I don't use that very often. I mean I have used it maybe once. I usually just have a good understanding of the code and I know that. And I am actually during this development I know the baseline as well. Okay this is how other libraries are performing. So we have to do at least better than that. So yeah I didn't use profiler very much. And I don't think I will use it very often ever even in future because based on the understanding of the code I can always figure out this should be performing. This is acceptable or not. I have a good idea of like this is somewhere in the ballpark. Thanks. In one of the slides you had this GHC option minus F. Something to do with inlining. Expose all unfoldings. What does that exactly do? Yeah so this is not use it. And the specialize aggressively all of these. So actually two questions over here. Good question. Expose all unfoldings is equivalent to marking everything in lineable. So everything is available for inlining. What does that do to the compile time? So it will explode your interface files. But it's just that the hifiles size will increase or compile time will also slow down. I haven't measured it. So and there was another aggressive inlining. Yeah so specialization, specialize aggressively. So this is another thing that does the similar thing to specializing. So it says okay there's no other control to say these are like blanket options. So blanket all everywhere just do specialize more aggressively. The compiler chooses to specialize this one function over another. So maybe this one I don't want to specialize in this one. In this case it says specialize as much as you can. So follow up question. Now say there are some you're writing an application. You're not writing a library. Your application depends on 100 libraries either directly or transitively as dependencies of your libraries of libraries. You want some of the base libraries to be compiled with these flags enabled. Yeah so this particular thing should be available in the interface file. So when you're doing a stack build or a cabal build. Do these packages like say vector, text, byte string which are used everywhere. Are these already compiled with these flags turned on? Or it depends on your application's GSE flags. So usually the writers the authors of these libraries they will expose the functions that might be required for inlining. So it's on their description. But if they didn't do that then you may need these options. For example expose all unfoldings. In a stack for example you can say or even in cabal you can say that all the dependencies should be compiled with this flag. So in that case all those functions available in those dependencies they will become available to you for inlining or specialization. These flags which when you're compiling your applications executable the flags that you put over there are used for all the dependent libraries as well. So that depends on the build tool right. So you have a way to do that that all dependencies will be compiled with the flags that you are specifying right. You can control that using stack I think you can control. With cabal actually by default I think it does that the GSE options it passes to all the dependencies and that's that could be a problem as well. Do we have time for one more question? Do we have time for one more question? Yeah you can. So those who want to go they can go I mean you can continue asking. Can you just move to the specialization slide. There was something which talks about what specialization is. So there are two slides definition site and call site. So in I mean if. Yeah so this let me see this one instead of calling a polymorphic version of a function make a copy. So code this specialization has nothing to do with type classes right. So this is if you're writing a polymorphic function. You specialize the instances right. But instances are by definition specialized. Not really. So you can I mean say if you have the functions they may be polymorphic and some variable which you want to spend. So here is an example right. So this is a type class member function concept right. So I have a specialized to I am on ad instead of the polymorphic variable M. I can I can show examples offline. No so I'm so this is this works for any monad M right. And then you're saying I want to specialize it for Monad IO. Yeah. But how exactly are you specializing it for Monad IO. I mean if the compiler knows how to what magic assembly to generate. If it's specializing it for IO then why does it even need this flag. Just do it. Okay. So let's take this one offline. If you have any other question. All right. Thank you.


Welcome back guys, this is UNFINISHED, the only place where we get to finish UNFINISHED matters, we are talking about hooking in the CBD. And on to our next question, do you think allowing hawkers in the CBD to operate results in insecurities? Let me know what you think. Of course yes, they're supposed to make a place where they're supposed to be working daily, not everywhere in the town. Operating, they can just be allowed to operate but there should be restrictions as in there should be charges against pollution. It may or may not because you don't know who is who. Some people disguise themselves as hawkers yet they are not genuine hawkers. There are some other plans, yes, so it depends. Okay, I can say it is not like 100% that all the hawkers are real hawkers. Some of them are not hawkers, some of them have other plans. As for me, I don't think so, because I don't think they are genuine hawkers. Security, okay, as I said earlier congestion brought by hooking in the city can bring, it can increase maybe theft because in congested places you find that thieves can get a good chance to maybe pick pockets, snatching, I think it is brought by congestion in the city, so I think hooking can contribute in a way. I don't know and I don't think so. Unless there is a point or unless it's proven that it is hawkers who maybe pick pockets other people but so far I do not really know who the pick pocketers are. But actually I think I've seen hawkers contribute to pick pocketing, so I think maybe to some extent yes. But unless we pin it down to yes, we've seen the statistics, it's always the hawkers who are selling, yeah, that's when we can pin them down. Well, something just came in my head right now, at times, at times see yes, okay, it's a yes or no answer, yes. So yes they do and to some extent they don't because these are just basically young people and people who are families to feed who are just, who cannot basically afford a rental stall to be able to run their business. So these are people, these are business people like any other business person. Okay I will say 60% yes because not all of them can be trusted because you find some take advantage when you sit at the window, you know they come snatched your phone, others they're just there to do business, so I'll say 60% yes. Also not really because let's say for instance what one has snatched is him at an abounder border, they're not necessarily hawkers. Maybe to some degree I'm not going to buy something from a hawker and as a footer but not much, I'll contribute some not to insecurity, yeah. What we're able to do is to see hawkers. In security, No, you know first of all hawkers are traders, they're businessmen. The difference between hawkers and other businessmen is that, But according to me, insecurities come out easy and hawkers have the end on it because we're all purposely put after do. And security and easy is very different from hawking. Just as the past question I'll say 80%, because most of them, when you look at the business they actually operate, some are genuine but some you can't understand, maybe they can get another location, they can go do business there and then when you follow most of these people, maybe some are engaged in these criminal activities but some are not, but I think they should just be controlled. If they are controlled then the issue of insecurity, the issue of overcrowding can be dealt with. I don't think so. Okay, they are doing their own business. It doesn't result to the insecurity in the CBD. Maybe other people can interrupt the things that happen in the CBD that will lead to insecurity. Somehow, yeah, but see the same everywhere. See the same and they cause insecurities because it's not like they come following people. It's only that they are just along the pavements so when you are interested in whatever they are selling, then you can approach them and purchase things from them. So I don't think it's causing insecurities. Some are harassing people and pickpocketing. Like, some of them are going to go bankrupt. Some of them are confused. They have their friends there who are pickpocketing us. So some of them are going to go bankrupt. We wake up in the morning, we are not going to concentrate on someone, and that's why some of them are going to go bankrupt. So they contribute much. When you are in the streets, them as well as the staff, so that they are able to help others to get back to the house, chances of being picked up will increase. There is no security here, there is no government. There's no protection.  For instance, if you want to say that I'm not your thing, let's not defend as a lady. Let's say I'm a man. If I were a snitch, I wouldn't do that. No, no. So, security is not my thing. Security is not my thing. No, no. I don't care. Security is not my thing. It depends on which way. It depends on where you live, where you live, where you live. Security is not my thing. Security is not my thing. It depends on where you live. Security is not my thing. So, security depends with yourself. Me and you. I don't feel like allowing hawkers in the CBD is a way of letting insecurity into Kenyans because we do have people who disguise themselves as hawkers even though they're not. And then later you find yourself in Kilimani if you know you know. But then again, I feel like it's the government's responsibility to make sure that we as Kenyans are safe. Onto our next question. Do you think hawkers should have specific hours to walk in the CBD? I think so. They're supposed to be given particular time for walking and their place to be. In CBD. Yeah, they should be given specific time. According to my opinion, they should be given specific time. Because maybe due to security, there's a security pair who are not allowed to work at a time, a speculated time to cut out their business. Not specific hours. They should be put in a designated place not even specific hours. They should have their places to operate on, not in the CBD. When you talk of designated hours when you tell them on Sundays you'll be in town they'll be cares in town. So they should be having a designated place. These people in this region operate here. They're not specific hours. They should be allowed to work in the CBD. They should have their place to operate on, not in the CBD. They should have their place to operate on, not in the CBD. They should be given specific time. Yeah, definitely. Because these are people who are fighting for their families. Some people, these are daily jobs. This is what they depend on to feed on, to collect rent, you understand. So this is something that they should strategize the government plus the hawkers. They should have specific hours to work, you understand. Maybe in the city, the city is busy. Maybe, and I think the better resolution to that to be, maybe having points for these hawkers to do their sales. If they're spending on the roadside, if it is possible for the county government to maybe have like a market for them, I think that would be much better because I think they're trying to maybe find something to put on their table, and that could be their only means to do in it. So instead of having specific hours to stand by the roadside, if it could be possible to have specific points for them to sell their products, that would be much better. I feel they should be given specific hours just like any other normal business. They should be allowed at least to run from morning hours to five because I mean that's their job. So it should be treated like any other employment. It's just that theirs will be self-employed. No, no, no. I would not support that because he knows his time best. So he knows where to open, when to close. Not really. Not really. There's a time when people say that it's not good to be at home. It's not good to be at home. So maybe it's not good to be at home. It's not good to be at home. It's not good to be at home. It's not good to be at home. They can just hook at any time but in an orderly manner. Of course I don't agree. Because when you hookers they are normal citizens and you cannot limit someone to do business at a specific time. But if that time that you have been specified and timing maybe personally I'm saying that hookers should be allowed to trade or to do their business the whole day. I mean to the same other traders. So me I cannot encourage government to give hookers a specific time because they are Kenyans and at the end of the day they have to put food on their table. So they are supposed to be allowed as long as they have paid tax and they are followed the guidelines. They are supposed to be given the full time, the full mandate to do their trading compared to other businessmen. 80%. Because when they have the hour then the issue of control now will come in because they will be knowing that from this point to this point this time frame will be having hookers so we should be taking control of them we should be ensuring their security there should be cleanliness of the area. So I think they should be controlled. Yeah. That will help at least will assist to decongest the CBD at least in certain circumstances. Yeah. I agree especially when it's rush hours it causes a lot of commotion and it causes a lot of commotion and it causes a lot of commotion and it causes a lot of commotion and it causes a lot of commotion because you never know when someone will buy from a hook so they should work every time and if they have freedom they can work anytime because they might find a customer at morning so they should work anytime. Anytime they can sell anytime because we don't know when someone needs anything.  To my view, I don't think that is right because maybe you know you know you know you know you know you know you know you know you know you know time factor doesn't matter because you can work anytime So on my opinion I do feel like designated hours can work but it's better if they are designated places they can work from morning to evening avoiding cares So we have come to the end of this show thank you for watching thank you for staying tuned do not forget to engage with us and do not forget to follow me your host SK Gichanga till next time, bye


We have ourselves a very unique situation for tonight in daily fantasy baseball where the main slate is just six games Which means for our typical template of DFS show where we have three pitchers three stacks three things to watch We kind of can't fill all the slots So instead we actually have a fun chance to go Pitcher by pitcher and break down my thoughts on every single guy on this slate Let you know whether I want to use them as a pitcher whether I want to stack against them Whether I want to do neither maybe both break down my thoughts on each guy So I do that for today break down each pitcher on tonight's slate for daily fantasy baseball to get you ready to submit your line-ups over On fan dual calm welcome on into the solo shot That's right here on the fan dual podcast network and number fire calm. My name is Jim Sonnis I am the managing editor of digital media for a fan dual research here to break down Thursday's main slate With a three-game slate with lock set for 705 p.m. Eastern There's a chance of rain tonight in New York for the Mets and the Nationals Doesn't look to be too bad winds are out to write at 14 miles per hour So I would bump up bats in that one It is 102 degrees in St. Louis for the Cardinals and the Cubs big bump up to bats there as a result of The hot weather that will impact the way view the stacks for today We'll dive into what that all means here in just one second at first We got some exciting news over at number fire beginning now You can find all the number fire content from the analysts You know over at our new home called fendal research fendal research is on the fendal domain Meaning you can now do your research for on the same site where you place bets and submit daily fantasy line-ups And don't worry all the number fire tools are still in place over at number fire comms Your daily process can remain the same for now as they thank you for your years of loyalty We'll be running free rolls over on fendal research now through the end of NFL season Check out this week's free play for the women's World Cup actually that is already over next week's free play check it out Over at fendal research will post up on that next week Congrats all you who were in the free play last night Hopefully things went well for you in the 1-1 draw for the United States against Netherlands free play again next week That sounds like maybe some priests and NFL So check that out over at fendal comm slash research to get the exclusive link Pitcher by pitcher breakdown for today in daily fantasy We got Cody Senga leading things off with a salary of ten thousand six hundred dollars followed by Justin Steela ten thousand Tanner BB or Tanner by the is at ninety six hundred dollars with Dylan C said ninety four Josiah Gray is eighty six with Miles Michael is checking in at seventy eight hundred dollars The way I figure we go for this for today is to go pitcher by pitcher and breakdown in order of how much I like them As a pitcher for the pitching slot over on fendal, which is why we'll start things off with Cody Senga Senga is at home against the Nationals. It's a great matchup Even if it's not a high strikeout matchup the Nationals don't strike out a lot against righties 19% strikeout right there, but they also don't walk which means Pitch counts against them should be pretty efficient Senga is already been improving with that I was talking about him last week with Rob Freeman pitching Ninja on covering the spread He said that Senga told him that it took a while to get used to the size of the baseball Imagerly baseball, but once he got used to it He was able to throw his all-speed stuff better and that's reflected in the data Across the past seven starts Senga has cut back on his foreseen fastball usage He has a 31% strikeout rate in that time. That is the best number on the slate Importantly the walk rate is also down to 8% and that's been something he's been working on all year again A lot of walks early on much better recently and it's led to a 3.42 skill interactive ERA in this time and the bad of all data has gotten good as well So even in the low strikeout matchup I have Senga projected for 7.2 strikeouts. That is the best mark on this slate So I'll put him second or put him first as well So to me code is saying get number one as a top pitching option for tonight I'm gonna put Dylan C second both. He and Justin Steele have tougher matchups But I like sees his situation overall more He is at home against the Guardians cooler weather for this game than what Steele is dealing with that's one thing As we discussed earlier in the week the Guardians offense is trending up and they still never strikeout So we don't really want to use pitchers who are facing them But Cease is just a better fit for DFS because he gets more strikeouts He's had an up and down year so far, but it has been much better recently Cease has an ERA at 3.00 since the start of June He has 70 strikeouts and 51 innings If you expand that and look for what I would need to be his most relevant sample That's the 15 stars. We've been throwing more forcing fast balls got the confidence back in that fastball In that 15 start sample. He has a 29% strikeout rate His skill interactive ERA is still kind of high at 3.81 mostly because of walks and fly balls And that's why I'd rank Senga higher in terms of pitching options for today But Cease can still get strikeouts even in a tough matchup I've got a projected for 6.3 strikeouts which ranked second behind just Senga And that's good enough for me to put in there as well I would say that because of Cease's batted ball issues You could also consider stacking against him. I probably get there with Senga just because the opponent's not that great The batted ball data is pretty good. I think you could consider stacking against Cease I would not consider stacking against Steel who's gonna be the third right pitcher I'm not sure if I'll get him a pitcher either, but I also don't want to stack against him He's facing the Cardinals who are a good offense against lefties, but Steel has been very good this year He's letting up just a 33% hard hit rate with a 32% fly ball rate And as a result, Steel's expected the array is 3.27 So that kind of kills stacking against him He doesn't get a ton of strikeouts though and then makes it tougher to hang with Senga and Cease So you could defend using Steel for sure because there are situations which both Senga and Cease struggle and then maybe Steel just naturally winds up being the top scoring guy on the slate But I'm just not as high on him on the other two and again, I think I'd rather stack against Cease than against Steel So of the pitchers on this slate, Steel is the guy who's most in no man's land Where I don't really want to use with a pitcher, but I also don't really want to stack against him So he's kind of wound up in purgatory hanging out by himself Forthering pitchers Tanner Bybee, he has at least some appeals of pitcher He's facing the White Sox which does help in that regard But doesn't get as many strikeouts as Cease or Senga and his bat of ball data is worse than Steel's as well So I'm more willing to seconds Bybee than use him as a pitcher We have a 12 start sample on Bybee since he started using his changeup more often He has a 38% of our hit rate allowed with a 42% of fly ball rate on a lot of slates that's not going to move the needle at all but on this slate there are a lot of guys who do suppress hard contact and As a result relative to this slate, Bybee does let up a decent amount of impactful contact The White Sox are not a good offense It's also cooler here than it is in other games in the slates and that's why Bybee's in the middle But I'm more likely to use White Sox against him than use Bybee himself The last two guys are the guys I am most looking to stack against But I'm more willing to seconds Miles Mikolas than Josiah Grant I think that might be a bit different than a lot of people for tonight I will have to go against both, but I think the Cubs are the bigger priority for stacking So let's talk about why and dig into Gray here Gray is a tinkerer facing the Mets tonight and he's always trying to find the right pitch mix And that also means changing the way he throws pitches And it seems like he did do that with his slider nine starts ago The velocity and the movement on that slider are both very different now than what they were earlier in the year If you look at that nine start sample, Gray has allowed just a 32% hard hit rate That is the best mark on the slate He has let up a 38% fly ball right as well So a big, big improvement from what he did last year and earlier on this year That's why the Mets to me are not the top stack on the slate Even though I think they will be there for most people They are still right up there though Gray is still not getting a ton of strikeouts So let's pull out a ball some play And the Mets are a powerful offense They have a 113 WRC plus against righties with a 180 ISO and a 39% fly ball rate They rank either first or second in all of those categories So that's why they're stackable Gray being good prevents them from ranking first in terms of stack for tonight Against Gray we do want to prefer lefties He lets up way more fly balls and hard contact to them than to righties So it's not going to hurt Pete Alonzo But definitely does boost up guys like Brandon Nemo, Francisco Lindor, Dan Vogelbach Makes them more interesting So get Alonzo in there, but then bump up the lefties due to the matchup with Gray To me, the top honor here belongs to the Cubs in terms of stacking Again, facing Miles Michalis, Michalis traditionally has done what Gray is doing Where he has limited hard contact But that has not been the case recently Michalis has been using his change up more often recently His strikeout rate is low in that sample at 13% with a 4% walk rate Which means he's letting up a ton of balls in play And earlier on, that wouldn't have been a problem for Michalis Because he did such a good job at suppressing hard contact That's not happening right now though Because he's letting up a 38% hard hit rate with a 39% fly ball rate in this time For this slate especially, those are below average numbers The Cubs have a 104 WRC plus against righties Went off again last night in part due to the White Sox kind of being weird for a couple innings But it's 107 degrees in St. Louis, 102 degrees in St. Louis So very very warm, that's awesome for offense And they did just see him over this weekend So they're familiar with what he's throwing right now And they hit him well there So I'm gonna go with the Cubs number one I'm gonna go with the Metz number two White Sox three for stacking And then you'd get to like stacking against Cease after that So primarily those three But then Senga top pitcher, Cease number two Steel three by B number four Dinger calls Because we do still have Dinger calls for today Despite the abbreviated slate because why not For the boring one It's not boring because of the match I think the match was actually kind of fun But the boring is because it's a boring player who's very very good That's Jose Ramirez, he's facing off with Dylan Cease And again, Cease is letting up a lot of fly balls And a lot of hard contact more than any other pitcher on this slate So if we're hunting for just Dingers Either we can go against him So Jose Ramirez is gonna be the boring homerun call for today The fun one is the guy we discussed a while ago Pre All-Star break And we were talking about how he was improving his launch angle Getting more fly balls and leading to more home runs That's Brandon Nimmo, he's kept that up Nimmo now up to 15 home runs I believe his career high is 16 And he has 7 home runs in the past month So Brandon Nimmo Figured something out and is gunning for power And you gotta love to see it So Nimmo will be the fun home run call for today Boring one, Jose Ramirez, fun one Brandon Nimmo That is all that we have here for today on The Solo Shot As always, please make sure you are subscribed To the Number Fire Daily Fantasy podcast feed Wherever you get your podcast Leave us a five star rating on Apple Podcasts Or over on Spotify And again, The Solo Shot does go up every weekday On the Fanduil YouTube page And over on Fanduil TV Plus For Amazon Fire, Apple TV, and Roku devices If you've got any questions for me I am on Twitter at Jim Sonnis J-I-M-S-A-N-N-E-S You can also follow the Fanduil Podcast Network At Fanduil Podcasts And don't forget to follow Fanduil Research At Fanduil Research We'll talk to y'all once again tomorrow For a robust Friday slate Good luck tonight This has been The Solo Shot right here On the Fanduil Podcast Network


Hey everybody, Matt here for Leighton Sports Car Draping. Two boxes for Brian D. We have one box of 2022 National Treasures collegiate football and one box of 2021 Top's Chrome Formula One Sapphire. Good luck, Brian D. Here we go. We'll start off with F1 Lewis Hamilton, Cranpre Josepin, Aspen Sands and Resta. This is Matteo Nanini Aqua to 100 Lando Norris Leclerc Nikita Mayspen Aqua Yuki Sunoda 22 of 100 Lewis Hamilton Sergio Perez That's Max Verstappen. Nice Verstappen. This is Max Verstappen That is yellow to 199. There you go. Nice one Alonzo That is Fernando Alonzo Yellow to 199 and Max Verstappen on the back. Here we go, Brian, NT collegiate football This is our last box of the day and I have to get out of the way So I'll go ahead and wrap it up now. Be sure to grab up your boxes for tonight Sunday Funday breaks with Forrest. Also grab your spots for Grab your spots for tonight and then grab your spots for tomorrow as well With daytime baseball breaks over on the LSE baseball channel Forrest will be live tomorrow night doing more personal stuff in there. Spoiler alert. We know what's on the back then There's Tom Brady to 99 and the Modsauce Gardner rookie Otto to 99 This is silhouette rookie Jersey Otto to 99 Trey McBride rookie patch Otto to 39 Kyren Williams Jumbo patch to 10 Justin Herbert. There you go. Nice Herbert jumbo patch This is triple Jersey to 75 Sam Howell Michael Carter and Chavonte Williams 49 This is rookie tool relic Otto book Breeze Hall. There you go, Brian. Nice Breeze Hall. He's uh in my starting lineup Going forward nice Breeze and on the back probably saw this earlier stuck in the box That is a rookie patch Otto silhouette to 25 Garrett Wilson There you go, Brian. Nice box of NT collegiate football. That'll do it for your break. Thanks, Brian. Appreciate it We'll get those right out to you


Everybody forced here. We got 2022 Star Wars master work hobby eight box haste number six random mini box style So what we're gonna do open up the box here. This is the front. So these will be the it's like four and then four in the back So what we'll do is we'll take them out make sure the front ones are facing fronts First box is mini box one three four left to right second box beneath it It'd be five three eight left to right and then so on and so forth stack down and then the second stack down to be You know you you get it. I'll show you right here They'll put it up first as you make the mini boxes then we'll run the random here. So we're all facing So this is the front you designated that so I'm gonna take these out and face them frontwards The other ones behind it Same we're going left to right So again box one we got mini box one two three and four five six seven eight, right? Let's go ahead and Run the random we'll go ten times a couple of fives here names first one two three four five six seven eight nine and ten John B. Down to Arturo V And the box numbers here ten times one Two three four five six seven eight nine and ten 24 down to three John B. 24 1 Arturo 26 John B 10 Matt L 23 Francis D 7 Michael B 18 17 Andrew P 30 Sal C 11 Chris V 20 Don B 4 Chris V 5 9 6 Michael B 2 Andrew P 14 Arturo 21 Andrew P 27 Francis D 29 16 Aaron M 12 Jonathan M 8 Arturo 19 Don B 25 John B with 32 Jonathan L 15 Andrew P 22 Brandon S 13 Chris V 28 John B 31 Arturo with three Those over here get them Uploaded here comes the link for you. Let's see some heat. All right. Good luck everybody first time. I wrote this in a long time Masterwork itself again. This is 22 masterwork 21 masterwork came out at the end of 2021 They definitely put a lot of effort into this one to like revamp the product and just make it better Which is why Very here later. So number one John You're gonna get a Two auto go to autos for master box one hit could be a few a few different things to hit per mini box here Few different relics sketches autos Medallions. Let's see what we got. Oh man. There's a rainbow of a size ventures rainbow foil here Look at that. That's a 299 actually in the size ventures. We got an admiral act bar auto Tim Rose Hey, that's rap There we go box one and Tim Rose auto is Admiral Agbar the quotes here and Then K2so on the blue number number two It's Michael B with number two well Michael something going on there Connix and Bridger that is the stamp relic Darth Vader Remember to stamp Darth Vader a bit appealing. I'm gonna send a box wrapper with this one There's a little bit appealing at the bottom there under the Darth It's a cool one. That's the Princess Leia from a new hope there and Then Luke ones for Michael you got yeah All right, number three here. We got our Toro Sabine there You've got nice a BB-8 autograph number 21 to 50 Brian herring is the puppeteer for BB-8 Solid hit for your Arturo Who's it here? It's a cool one, man That's a Luke From a new hope there and a blue grieve cargo and number four for Don B We had both the relics about the autos Good luck dawn tech Soka base Got here sketch. Oh, we got a sketch Let's go a sketch for you Don. Let's see what it is massage bluestock a tonneau His base that's like the non-number base parallel there and a sketch Is Boba Fett's helmet right there I'm really Varlea bus is that how you say that? Visegas That's a tough one right there look at that Boba Fett's helmets Super sick congrats dawn good first box there two solid autos and awesome. No, no Devin. Don't know do that not for a Not not for Matt. All right second master box. You got five three eight Chris V with five and six in this one There are some insane autos that we can pull out of this stuff tonight for five We got Chris Chris V five six. Thanks for joining dawn. So dawn heavier Medallion in this one maybe a little heavier appreciate you Zero It is a Manufactured like medallion here the client Is that tools of technology medallion the client best scar ingot. That's how he paid a Mando Escar in Jabba there he is Turn the Jedi Jabba and a blue kazoo does I own over? Need a nice base parallel the parallels can get pretty rare, but they can be they can be monsters in this stuff Number six is also Chris V. I think that's real best car melted downturn in the armor for yourself Why would you got the the quotes here? I Have the high grounds. Yeah, you had the high ground. He we got a green Luke. That's pretty cool That's 35 and 99 in the Luke pretty good pretty good ninth sister They were pretty difficult to fight in the first game of that one Cad bane on the canvas. That's 1d5 awesome cad two numbered cards Luke and Cad bane are pretty good on a mini box here Chris again, and then a Java autograph very good mini box. They Lonnie shoe as Java Very very good mini box to get an auto plus the two numbered cards the canvas cat is sick Francis do number seven here Sean and Donnie did he go his job? Let's let you come for Halloween next year I don't think Sean wants to hang out with Donnie on Halloween. No Cad bane Canon jars on the blue Quill Kylo and a po dameron sourced fabric relic Nice po dameron shirt relic and number eight Jonathan M. All right. I'm ready to pull up our camel auto. I'm ready. Oh Ready to do that. I mean monster. That's a cool Poster there bubble with the bounty hunters invader there purple second sister to 50 Purple second sister to 50 Foil here then gar It's one of those bounty hunters you're talking about and the auto is Ezra Bridger Taylor gray as Ezra Bridger They're Super Bowl ring Are you gonna become a Niners fan shady? No dolphins I will say one thing Tyree for MVP. I will say that that's the only one that makes sense I don't know how purdy is the MVP for a hundred rounds insane. No Like if any quarterback is gonna be it it's it's Dak right now because of the numbers he's putting up But it should be Tyree If there's a nine or this should be it's McCaffrey or diva like they lost when diva was out and he came back and they're winning again What's up, Greg? What up, Greg? What's going on, man? All right, there we go. Uh, so what are we on nine? Yeah nine through twelve here number nine for Chris V again Sid What is that now? We got Mando on the stamp 12 of 99. That's a cool one the Tuscan Raider and Omega to ten number to ten Omega base parallel Right, you need help. We need help. We knew that though John be with number 10 Stuff it's like a maze John be with ten Still spots available the next few guys. We got a sketch. Yeah, it's a sketch. It's about the I believe it's a sketch Oh, yeah, it's a sketch. All right Cad Bane sure didn't weigh the blue Urso Harris and doula and the sketch is Yoda Mike Sealy it looks like Mike Sealy as Yoda as far as but with the Yoda here. Congrats pack ten John be That is super sick Super sick That is awesome number 11 Salsy here we go That's what we're dealing with guys a sketch every ten packs every ten mini boxes here Sounds good. Greg. It's also not nonsense. Don't say that. That stuff's fire, man.  He's not against all of us. But yeah, it's fire one of the quotes there And they called again iconic. Oh, you want to come to the goals? Blue John out.  Elspeth auto magistrate Morgan else with auto Diana Lee, you know, Santo She had a more expanded rule that's for sure and in a soca they probably have a bigger role going forward too Wait, she got She had a big role But I don't know if you guys watch the soca, but leading up to that was pretty fire It's a stormtrooper there purple peli moto out of 50.  What the hell was a Jake Hello there Obi-Wan Kenobi quote to 299 and an auto of pike traveler Alfred sing as pike traveler did a quad auto hit the quad All right, we're on 13 through 16 13 Masterwork is fire rich. Can you get that you're a car real quick masterwork is is gas There's a Lando on the poster green time at Revora to 99 Indian Vader and Autograph is teacher droid to 99 Chris Bartlett teacher droid. You did one of those for Sean line Teacher droid look at the sketch we just hit Masterwork has been fire. That was the second sketch of the case too Good stuff number 14 here Andrew P Card it looks like oh, oh, we're about to hit a sketch Another sketch. Good luck Andrew is about to get sketchy Greedo Sabine ran on the blue Dooku and solo that is an auto Morgan Elspeth Diana Lee, you know santo Green lightsaber. Oh my god.  That's a sketch right there God, dude, we've hit a ton of Yoda's today sabers dough Good lord, that's so good Say Steve Iyoki Whose auto is that it's like Steve Iyoki or something. It sort of looks like God, that's nice. This product is just Yeah, that's good It's good Jonathan L with 15 here Looks so mad. I wouldn't hug you He would force to capitate my head. I think Alright, but the Obi-Wan quote so uncivilized Fennec shan in the blue Marin Owen Lars and FN 2 1 9 9 autograph David Accord is the voice of FN 2 1 9 9 That's the one that uh Fighting Finn. I think You got got and I think the end of the first second one at one of the movies God The Boba again, those are cool, man. I think those cool-looking posters cursed Santa in the blue Fifth brother got a foil IG 11 the IG 11 the 2 9 9 in the foil and autograph acts wolves Simon Casanide does acts wolves Go dolphins go you know, I heard that I Heard that dolphins go Yoda. Yeah, what? Let's don't go together We're on to 17 here now 17 to What would be the next 120 17 through 20 that's the next grouping of four I can count Just takes me a few minutes 17 I want to see a monster auto now the sketches are super sick Don't get me wrong, but we need to see a monster auto Sam pulled a bokeh tan auto road. That one was awesome. I already got Koska Reeves Meigs Mayfield That is an auto dr. Pershing. So oh meet up Tahit in 99 looks like Michael Daniel It does like Mike McDaniel She's running out the field dude. Yeah, man Mother Obi-Wan quote. That was when he uh, finally Killed Darth wall and then purple Bayes Malbus to 50 50 50 Bayes Malbus Are you in one of the master work breaks? Yeah, he got Michael be again with 18 Yeah, exactly It's just like Good office. What is that? What do we got here? I don't know what we got here Let's do this. It's the chewy sample the wood part of this earlier of this same card Well the wood card that was super sick Bokeh tan on the blue and Ohtani on Mark Hamill auto foil a size ventures to 299 There's a Lux Bon Terri auto And an extra hit here Lux Bon Terri is Jason Spesak and green Mandalorian commemorative stamp to 99 nice Mando two faction Star Wars One-on-one already ripped Star Wars We ran them off the numbers in the beginning of the break depending on what break you're in and then we just go In order of like the mini boxes as they as they kind of sit. This is 19 Arturo Do you know what break number you joined? Toro at 19. It'll be one there grief cargo on the blue Major von reg Commander Pire and an auto of Sabine Ren Tia Sarkara Sabine Ren You got to go somewhere shady, right? Yeah, one-on-one already took place I can give you the link for that one that happened before this break We have the recording uploaded right here. So here's the link for that one And what about 20 20 for? Krispy Yeah, I mean they have to if you can go undefeated And in the ACC and I make the playoff then yeah, you have to move ACC is done. So they're green k2so to 99 a 2 to 99 Bob there he is there he is and There we go fennec shans sourced fabric relic green parallel 90 of 99 some gloves Shooting gloves nice fennec We're on to what 21 through 24 now 21 is our Toro Jordan, I don't know you have to give me some more info buddy. Well, that's a sketch You can tell because it bleeds over that's a sketch in the middle This one could be pretty sick man Yeah, well, they have so many different artists. You don't see someone like paint on them and stuff Cobb Vanthin the blue Chewy Dude, what is this got like a sky blue background or something? Oh? Wow, look at that sketch card Dan Loller Was that the Jedi that Amad best the guy who voiced Jar Jar said the Jedi that he played in the Demento Cameo looks like Kanye. I'm almost I'm not sleeping now. We're magging that Very nice Pretty good detail. He's there 22 Andrew P here Greg says he believes so yeah, Greg definitely knows That's the Star Wars expert For sure Yeah, he did say Brogu Did he did do that Only a sith deals and absolutes Tamra vorra on the blue Krennic and a BB-8 auto Brian herring as the puppeteer for BB-8 Andrew P with 22 23 Yeah, I don't remember his name Yes, it was Matt hell with 23 and though their purple tamra vorra number to 50 language foil of Wicket to 299 that's a cool one and a Leo or Ghana to 50 on the commemorative stamp You go 23 a good one there a few numbered For a Matt L and John be with 24 here long monster auto at some point tonight. Come on at the Imperial Guard Poe Dameron Axe woes agent tyranny and an auto of record deep Bradley Baker One of the many voices deep that the Bradley Baker does a record solid hit there his autos do pretty decently Okay, now we're on to 25 through 28 here ask cool cliff. That's crazy man 25 here for Don Look Don already hit a sketch in the break thick card That's a medallion That's a cool Luke right there Blue Mace Windu all 337 BB-8 Wow, that's pretty cool the sith dagger palpatine relic here. Oh She's blade to 2 of 99 here The medallion card Okay, you had a lightsaber Who gave you a lightsaber? 26 for Arturo to hit all to hit both of those things Yeah, man a boss That's Boca tan crease number two of ten. That's a big card number 26 for Arturo Boca tan to ten on the orange That is a biggie big time character now in the Mando skew of things Boca tan going into a mag crosshair grand inquisitor and a ray Sourced fabric relic Ray source fabric relic That was a very good Very good mini box. Are we got Andrew P with 27 now? It's great going on about now What's he doing good? Jaw was there Obi-Wan in the blue old Obi-Wan foil of Boba to 299 And a Saw Gerrera autograph that's Andrew Cachino as the animated Saw Gerrera. All right 20 28 here Chris V. They'll have gone a Chris Santon foil that one's numbered to 299 Nice Chris Santon deep Bradley Baker echo auto foil to 50. That's very nice Congrats again Chris V. Obi-Wan quotes and a green jinner so to 99. That's a really good mini box, too There's actually something in it How do we get some new eyes sit inside? All the dust flying around here probably all right 29 to 32 Francis deal with 29 Andrew P 30 John B with the last couple 31 and 32 Francis 29 got more of these right after this guys you have two sold out after this Or just once like this. We'll check in a minute here stormtrooper there third sister on the blue rash Tamara Bora autograph to on way Raina. Oh, and it's to on way 30 Andrew P Thank you all for joining all the breaks tonight. Whoa. Whoa. That is thick dude. This is Super thick It's one of those relics you're gonna need like a I Don't know what you're gonna need for this Carson Tava finjaba green Jar Jar five of 99 Nice green Jar Jar and it's sure it in way Prop rock it's like the clear screens used like the maps and stuff on screen proper like sure Yeah, rebel base radar screen. That's pretty cool, man prop action there I don't have to go in something gigantic and Then the last two here for John B. Good luck John 31 and 32 So that's a literal large card Okay, I'll be one quote. There's a blue bobboo freak. That's my guy right there. Yeah Skad I'm a skad Leia and Cobb Vanth very nice at Timothy Olafant auto 17 of 99. That's super cool Here we go John Timothy Olafant auto to 99. I Was hoping he would sign glad he did Very cool. And last one for you John Toro Callican Lando Kairissian on the blue What do you wrote that is a foil Leia? Wow really like that really like that 160 of 299 in the Leia From a new hope like that a lot like this to sketch card on the back. It's a poor Oscar Chavez with the poor sketch. That is very cool John. You killed it at the end there. Oh Right y'all that does it. We're moving on to case number seven super fun stuff, man


Within Hogwarts Legacy there are specific chests which can be found all over the map which reward you a guaranteed legendary piece of gear. You can exploit these chests to give you the gear that you need. To do this once you've found a chest that looks like this do not open it but create a manual save. Then go ahead and open the chest. If the legendary gear piece isn't something you want and need simply reload that save you just made and reopen the chest. Do this until you get what you want. Guys check out my channel for more Hogwarts Legacy tips.


Now many financial institutions are studying the topic, kind of, and I'm starting to understand that if you have permission and known and identified actors, maybe federated actors validating the chronology of the blockchain, they don't need proof of work. And many of them are also understanding that they don't need blocks because they can just sign every couple of transactions and they don't need a chain. So, when they understand that for the private blockchain they don't need blocks and they don't need chains, do you think it is worth the terminological battle for, say, for clarity to tell them, well, you are not doing a blockchain, we should strategically just leave it be, okay, you are doing the blockchain, I will keep the Bitcoin world. Wouldn't it be more honest and more useful for clarity just to stress how much a replicated multi-master database with digital signature without blocks and without chain is not a blockchain?  What I really want to do is clarify the issue. So to me, when I use the term open blockchain, I'm clarifying the issue by saying open is the characteristic that matters and here's why and here's what you get with it. And the blockchain part is really an implementation detail. The blockchain is the best way we have found to do open decentralized global consensus. But as a technology itself, it's not that interesting. The blockchain is the least interesting part of Bitcoin. What is interesting is not even, the proof of work is much more interesting, but what is really interesting is when you combine all of these things together and then make something that is non-national and independent. But again, I don't care. And so when you are presented with the word blockchain, that is not an answer. That is a prompt to start asking a lot of questions like what is the consensus algorithm? How decentralized is it? Is it open to innovation? Is it open to permissionless innovation? Does it afford anonymity or does it afford privacy? So we have to remain to open blockchain law. Is it censorship-resistant? Is it censorship-resistant? And is it also coercion-resistant? And so the important thing to me is this. In the next 20 years, we will live in a world of entirely digital money. This is not a possibility. This is a certainty. We will live in a world where the vast majority, if not all transactions, will be entirely digital. And so we have a choice. We can live in a world where the norm is one in which our identity is tied to every transaction. And we voluntarily give the power of complete financial surveillance to whichever government we elected last week, hoping that this one is a good one. And knowing that the next one could be just as crazy as the one before. Or in many countries knowing that there is not a good thing about them, that they are evil in action. We give the power of full financial surveillance over every human being on this planet to centralized authorities. We are walking down a very dark path, a path in which when you say the wrong thing, your bank account disappears. When you go to the wrong protest, your life savings disappear without judicial process, without question, without answer, without recourse. That is not a world I want to live in. And the alternative choice is a world that re-establishes the fundamental balance between the governed and the government. And that is a world in which individuals have transactional privacy, as we have had for millennia, without horrible things happening. Because most people use their money to buy food, shelter, healthcare, clean water, and to express themselves. We can live in a world where we have complete privacy and governments have no secrecy to hide behind. They are forced transparency, which is the way the balance should work. We live in a world where there are no borders for our ability to trade and do commerce with the people of this planet. And a world in which everyone can participate. This is the choice we face today. The future is digital money. The question you have to ask yourselves is, what kind of future do I want to live in? And that is a really important question.