Obsessive Coding Disorder, Julian Storer - JUCE Summit keynote 2015

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Would love to have the code and run it through a profiler. That use of an exception to replace a goto in the state machine is a bit nasty though. Using goto for that is completely legitimate even in modern C++.

The inlining issues could probably be solved with functors instead of a macro mapped to compiler specific extensions. Functors taking parameters by reference are almost always inlined.

๐Ÿ‘๏ธŽ︎ 12 ๐Ÿ‘ค๏ธŽ︎ u/peolorat ๐Ÿ“…๏ธŽ︎ Feb 11 2016 ๐Ÿ—ซ︎ replies

Great presentation, thanks for posting!

I really think that, while it is definitely possible to write awful unreadable and complex C++, modern C++ makes it easier to come up with simple, elegant, readable code that still performs well.

This is why I don't buy the argument that C is simpler and easier to reason about than C++. No, look at zlib. It is in no way alone, many popular libraries have similar code bases.

๐Ÿ‘๏ธŽ︎ 19 ๐Ÿ‘ค๏ธŽ︎ u/entity64 ๐Ÿ“…๏ธŽ︎ Feb 11 2016 ๐Ÿ—ซ︎ replies

The presentation was put together very well.

๐Ÿ‘๏ธŽ︎ 4 ๐Ÿ‘ค๏ธŽ︎ u/esoteric_monolith ๐Ÿ“…๏ธŽ︎ Feb 11 2016 ๐Ÿ—ซ︎ replies

Very nice. Couldn't agree more with turning this into a header file instead of ten objects with autotools and a complex build system.

I had no need for the compression portion, so I took out the core decompression alone and got that down to 7.8KB at 336 lines of code. Then I factored out ZIP, GZIP and PNG support to other small headers that build on it. But I didn't really take the time to master the intricacies of inflate, and instead it's very much the original C code wrapped inside C++ still.

๐Ÿ‘๏ธŽ︎ 6 ๐Ÿ‘ค๏ธŽ︎ u/[deleted] ๐Ÿ“…๏ธŽ︎ Feb 11 2016 ๐Ÿ—ซ︎ replies

That was great.

๐Ÿ‘๏ธŽ︎ 2 ๐Ÿ‘ค๏ธŽ︎ u/realfuzzhead ๐Ÿ“…๏ธŽ︎ Feb 11 2016 ๐Ÿ—ซ︎ replies

License, Copyright? I'm intrigued. About what he says around 36:33, is that true?

He discusses the copyright of the resulting code. He says if he refactors enough so that there is no original code left, the code is his. Is that right? Refactoring some code can make the result not a derivative work?

๐Ÿ‘๏ธŽ︎ 2 ๐Ÿ‘ค๏ธŽ︎ u/asegura ๐Ÿ“…๏ธŽ︎ Feb 12 2016 ๐Ÿ—ซ︎ replies

removing all dependencies.

I was not aware of zlib having dependencies in the first place?

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/[deleted] ๐Ÿ“…๏ธŽ︎ Feb 12 2016 ๐Ÿ—ซ︎ replies

Fun and interesting presentation, but I also see the portability of older platforms as one of the old code's strengths. This refactoring would likely abandon support of those platforms.

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/codekiller ๐Ÿ“…๏ธŽ︎ Feb 12 2016 ๐Ÿ—ซ︎ replies

Very good talk. In the C++ code the columnar formatting is a bit too much obsessive, and I think some C++ lines are too much long.

Now I'd like to see the C++ code ported to Rust, to see if the performance changes, and how the very strict Rust language leads the code and the programmer :)

Edit: to produce a sufficiently efficient binary from the C code it suffices a faster, less optimizing, simple(r) compiler (like http://bellard.org/tcc/ ), while to do the same from the C++ code you probably need a more optimizing (and more complex) compiler to remove the abstractions (like the lambdas), and probably more RAM to compile the C++ code.

Edit: many of his improvements are possible even if you don't leave C99/C11.

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/leonardo_m ๐Ÿ“…๏ธŽ︎ Feb 12 2016 ๐Ÿ—ซ︎ replies
Captions
it's the first juice summit I've got their keynote so what what should I do I didn't want to just go up there and do a predictable history of deuce or what's new in juice for sort of talking about features and things the whole conference is around use that there's workshops and lots of other places where you can get that information so I wanted to do something that's a bit more bit more general a bit more entertaining a bit more of a bit more left-field so my my programming career has been going pretty well so far I get to write a lot code a lot of people use that code it's all public lots of people look at it lots of people criticize it lots of people say nice things about it the most common compliment like get about it is that people love the readability they say it's really readable it's very concise and well-written and that's really satisfying to hear that because that's exactly what I've always been really striving for now from my point of view when I'm writing code I don't it doesn't seem like I'm ever doing anything particularly clever or difficult I just seem to be paying more attention to detail and spending maybe putting a bit more into the craft side of it than a lot of other people do and when I look at other people's code it does the kind of generally look a bit ugly so I guess you know there's something there's something in that but so I thought I'd use the keynote to explore the things that I tend to obsess over which seems to be working out pretty well for me and hopefully will be inspiring for other people to try and take more of this the mindset that I've approached coding with in their own work program is with pretty straightforward try and think of what I can do for you guys that you're gonna enjoy so we've got room for the programmers you know we all love showing off we all love criticizing other people's code that's the best fun in the world we love doing stupid stunts things that are difficult but actually kind of pointless we love arguing over stats we love saying this is faster this is slow and we love a bit of recursion we love we love things that are kind of meta and look at themselves and recursive ways cuz that's just the kind of smartass as we are we also love learning fact coffee will come afterwards so this is Kevin my my hit list of things I want to wanted to do in in this talk so something we've had fun doing it Roley is the code makeover and this is a great little exercise where someone volunteers up a mediocre piece of code they've written we sit in a room and the code is we publicly shame that code and we try to aggressively go around and prove it rewrite restructure just fix everything from like the the lowest level bits and bits of obvious bracketing in the wrong place you know whitespace problems right up to like actually does this need to be a completely different architecture and it's a bit like watching those TV shows where a group of like people in protective suits goes into the house and more obsessive hoarder and starts clearing out bags of rubbish and try and turn it into something nice it's so it's kind of it's quite compelling it's in a kind of car crash way watching this and we've had some fun doing this so I thought what I'd do today is do one of these sessions and refactor some code so what should we refactor I I started doing this about a week ago and when I had the idea for doing this talk so I thought well I'll pick something easy because the my aim was to come out with at the end of this with actually a reef something that was reef active where I could talk through the process involved and show you hey you know this is the result so I chose to do this I know you all know what this is right you can all you know what you can all read code from but it might be a bit small but this is actually probably running on at least a dozen machines in this room right now around the world this will be running on I don't know how many billion devices I might have been a bit over-ambitious inches of this but what it is is zeglen said lib factoids this is a 20 year old project it's C which is makes it easy for me to start that's a good easy cleanup target in itself it's about ten thousand lines of code billions of devices all over the world this is very importantly it probably has no bugs normally when we're refactoring our internal code you expect to come up with lots of bugs you'll be you'd be left right and center all over the place this is kind of an interesting one speak because I figured the last bug-fix in the in its git repository was two years ago and that was the last commit so it has been pretty well tested everywhere it's perfectly good the performance is great it works does the job funny there's nothing wrong with what I'm going to refactor if you think my child you've prayed gotten these on your wall and as a business this is participate perfect sense but and zeal impresses this with flying colors it's great it's probably got their boats it's well tested performs really really well you know if you're in charge of zedler page q you obviously as a manager you ship is done so really only an idiot would bother to try and improve something that already works perfectly well thank you very much so I thought I'd be that idiot you there are three types of code that you tend to see there's good code we all know what good code is it's enjoyable to read you read it it's it's like reading a poem it's beautiful it's well-constructed and it's fast it does the job in does it well and it generally doesn't have any bugs bad code is what your co-workers write or your students or your students if you're if you're a teacher it doesn't work and it's obviously not going to work because you just looks it and without even having to focus on them on the words you know it's rubbish you can see from 10,000 feet it's rubbish bad codes straightforward ugly code is the is the middle ground here and I put Zed live in the ugly camp because it works really well but it's not elegant and you start digging there it's it's ugly it works it's great it does the job if you want to compress something that's what you use but yeah it just feels it feels like it could be better so what I kind of want to get across in this is when when you're writing the library code in particular but any code taking more of a pride in actually not just making some of the works but making something that you're proud of that works is really is a really important mindset so let's let's get back to the 10,000 foot view do we really need all that just to compress some some code some data I mean this is 2015 now we have C++ 14 this is C this 10 personalize it say surely we can do this better given on modern tools given C++ 14 it doesn't need to be this big surely even worse this is just the source code before you can use this source code you've got a configure script you've got to run Auto conf it will generate some headers from some somewhere in here there's something that gets turned into headers if you want to use this you have to run it you have to get it you have to run config you have to then install it probably you have to then build it with maken okay so static lib and then you have to add some paths to your project to include the headers in the you have to add some Lib paths and you have to change your build so that includes the Lib and blah blah blah eventually you get to actually use this code do we really need to do all that I needed Zed Lib inside the juice classes and juice actually contains all of this code I hit it all the way by using some cunning tricks so that you don't actually have to build this as a static Lib it just gets me included and we just in sight hidden away in the juice CPP files we actually just include all of these C files and I had to hack a few things where there were symbols and stuff I made it build then I did this years ago and it's all been in there and you've all been using it for years without knowing it's in there and that's that that solved the problem but it still felt ugly to me every time I was going through the directory structure seeing like this whole directory of files in there that just didn't it's too much too much the big blue blobs are tables of constants but somewhere else in here is a little bit of code actually generates those tables do they really need to be there do we need to like spam the have all this stuff in our code base or is it you know is though do you even need these four things to be fixed tables the green areas are comments and there's a lot of comments in here because there needs to be a lot of comments in here because it's not very easy to see what's going on in fact it's very hard to see what's going on and you have to read the comments and that's it's it's good to comment but if it's better to write code that doesn't need it visible from space are these two red areas these are 800 line functions this this this they're both they're both switch statements one switch statement which is used as a state machine with some go twos at the end almost every case statement in the switch statement has fall through so the order is okay you know every time I've tried to run code quality checking software on the juice codebase it Flags this stuff up so there's some pretty obvious high level stuff we can do there's there's low-hanging fruit a lot of the nationรญs will go away just by choosing idiomatic C++ 11 over C some of the other nationรญs is going to require a bit more bit more intuition a bit more craftiness to fix it so I also promised that this talk would have some sort of recursive meta aspect to it so and some measurements so this is where they come in when I was thinking about what definite defines good code I figured well good code is as source as it can be without being any shorter it can it doesn't compress well if you write a really good piece of code it's not we all know that the good old DIY principles we don't repeat ourselves so there's not a lot of repetition in there there's not a loss of entropy is high basically and by compressing some code you can measure how high its entropy is so I figured it'd be kind of fun to use the code I'm writing to compress the code I'm writing and then see how big the result is so that we can see how much it compresses whether that's a this is not science this is this is this is this is just me making some stuff up I was my plan was to look at the compressed size and the uncompressed size of the code and to see what see what the difference is so I wrote the test programs which I had some unit tests for this and some benchmarking and since I was refactoring the code that was already inside juice this was great because I could do these on two branches and I had the drop in replacement so I could just run the same code before before and after to run the same benchmarks before and after so this was my this is the code size originally it was 300k after you take the whitespace out that compresses down to about a hundred K so there's about 100 K of information in the original I also the benchmarks mean meaningless at moment but that's that was the original performance I was really hoping I wouldn't and what I really liked it in the talk is say hey look how much faster - but and at least it shouldn't be any slower so let's get refactoring let's look at the start with the high-level stuff that's the original folder this is what I wanted at the end the first the easiest thing we can do the best way to actually get this code into a program is headers only there's no reason for it to be anything else you don't need to link this as a static Lib it's I mean I ended up with 3,300 I see code it's pretty trivial it's smaller than the stood stringing header there's no need for any CPP's no need for TOCOM this header can actually probably be split into two or three files because in there there were there's compression and decompression classes but though I also found there were some it's like a redundancy check classes which we're kind of a standalone thing so you could pop those out to other files it's all the same really it's personal preference so after dumping all the original code into a into one file I waited in there and King awaits trying to make some clear some space in the undergrowth and see what's going on first of all I strips out all of these wonderful type deaths we had was we have here we had three different definitions of long so we had you long we had you long F which is a far u long what's a far longer than that so then we had then we had somewhere else we we then define that with macro as z underscore young F we haven't uh Sh which obviously is a short we have an usher we have an H which is an unsigned char obviously then we have some these we use interchangeably all through the code base so first of all delete and some nice standard c plus 11 types which we know are going to be the right size and that that's lovely copy and paste I'm doing that I'm I've never so never been a fan of writing type thefts of the P on the end for a pointer that's a very Microsoft thing to do what I in in the code I may actually get rid of most of the pointers anyway turn them into references but it always feel something like if you're going to have a pointer put the star there make it obviously a pointer so you can see you kind of use it as a staff as in yeah do you really want a pointer is there a better way of doing this so it's nice I think not hide it behind the a type def so if you want an example of how modern compilers and standards have made our lives easier there's some definitions in that old code that are quite poignant you can always see the tear stains on some of these we've got we've got an amiga definition down there apparently on the VAX if you want to use F open you have to write some assembly language there's Atari stuff listen this bit here is this bit here is for platforms that don't have men copy so it's kind of like looking at cave paintings of saber-toothed Tigers this stuff so anyway so it was nice to put that stuff out of its misery and this already the codes shooting down shooting down before we have our for some reason we had a whole allocation system with macros and things called Z elegans dead free this let you add your own allocator to the library because obviously when you're allocating a few K of memory you need you need to supply your own allocator for that the the algorithm makes it doesn't yeah it doesn't leave much much space I could probably have made the whole thing just run on the stack with apps no allocation in the end though I kept I kept using some heap heap allocation but obviously I did that with ra รญรญ- and some juicy pop classes which actually ended up being in about three different places it was really there's really no source of allocation needed in this in this code next fun thing was to take all of these randomly styled definitions of well constants and state flags and things and turn them into modern super to serve an enum classes which was really nice to forcibly go through but the compiler then makes you go through the code and makes you clear up all of the uses of this because everywhere in the code it was in being used as every kind of possible flag and meaning so actually using elem class means you're forced to name everything properly so all the types become much more readable there's a kind of ripple effect through the code that improves the overall structure the also I mentioned move most of these out of the global namespace and into private hidden away sections of of classes so in fact even though you this is headers only and the whole thing gets pulled in none of this is gonna be there's maybe ten different definitions that actually need to be public the rest of this just gets hidden away and is inaccessible to the users there's actually it turned out after digging through it for hours there's really only three structures in that and given that it's a pretty simple data model they've managed to do it in a very convoluted way so we had we have a dead stream which is used for input and output and what you have an inflates take in the deflate state which is defined obviously in a different way to that one but and then the zoom has appointed to us to a thief and then deflate state but it sometimes cast that to an inflate state pointer and uses that and then that has a point of bank these have a pointer back to the thing that they're in and none of this is needed so that all went and I ended up with just two public functions which is all you actually need to see but the compressor compressor they'll have a few they few public functions with enum types of status codes and then big private sections where all of the stuff you don't care about happens naming is probably the most important thing in programming if you've got good names then your program kind of writes itself they're descriptive good names they're abbreviate they're not really boo visit these are some there were many many name changes that improve this code this is some examples so rather than saying unsung castes fast are next and then labeling it with a comment next input just call it next input hold is apparently a bit buffer I'd without knowing what a bit buffer does or what it's for obviously you call it bit buffer unsigned copy I mean what what is that is that a noun or a verb I dig in a bit you read the comments you see where it's use oh it's a number of bytes to copy okay okay this no it's obvious stuff and in your own code when you you know you'll be writing something and maybe on the first pass you throw in a few a few quick names but it's always good to go back and say when someone else he doesn't know what's going on reads this what are they going to think and imagine that person is aggressive and they're going to share sat you so so go back and rename also the constants I get that and being C it's always really nice to me to take some C code and you see all that big block of variables at the top of a function you go ahead and just move them down reduce the scope you should if you're a really good program you've been doing this for years you'll get a little in a sigh of satisfaction when you reduce the scope of something whether that's making it private or whether it's just moving the scope down a variable away it's just like putting things out of harm's way if it doesn't give you a good feeling then you're not you're not trying hard enough so there's two types of crc redundancy checking going on there's CRC fifty-two and Adler thirty-two I don't really understand what each of these things do but I unpacked it and I rewrote the code so doesn't matter what the details I'll come back to this one minute but that was the original CRC and that was my rewritten CRC ah maybe this is Adler this is Adler I'll show you see and see in a second but it's really it's always very nice fiying when you take something that's rambling and sprawling or that and you down set something that's fits on the screen this one's the CRC this is the one with the big with the big constant table in that what I've done here although it's a bit blurry you can see this I'm not gonna next slide the CRC table I wrote the I tried a little bit code that generates it it actually takes like a few microseconds to generate that code so delete and very very very nice sort of fun simplest thing we can do here is to have an inline class actually inside the function it's on the next slide with a with a static down the bottom here a static initializer for it so it's it's only ever going to be initialized once it's going to take a few microseconds when you're when your program starts up but the entire whole thing is hidden away inside this process function and that's the only place this is needed so all completely scoped away out of sight there are other room other bits of consultation in the sketch around the library which you hit this kind of with very big ones it's obviously gonna be better if you can replace it with code but there's a sliding scale and the smaller they are the less likely it is to be useful I'll leave as an exercise for the user whether you can replace that with either a context Pro or some template metaprogramming to actually eliminate it altogether but actually in this case I would I wouldn't do that because I think the compile time overhead especially for us for headers only library for the compiler actually generating this and the extra binary size probably outweighs the the advantages of having a table whereas this is going to be a tiny bit code tiny runtime overhead and it's gonna work brain work perfectly well ok macros must die and I was I was I did eventually remove all the macros from this code which made me feel good but it was a bit of a struggle in places some some things were easy so like there was all this stuff with error messages that I can nicely place with a nice function that just translates those nice you know classes here rather than all these error return error message macros that were doing things with local variables all the way through that through the code one of the things that Marcos do which makes them very tempting and very useful but also very dangerous are that they can they can mutate local variables so this is an example that before of vary this part of a part of the CRC where it it's using using a macro here to unroll unroll the loop 30 times and to and this duel it assumed macro works on local variables it works on both some local variables and member variables so that's something that's very hard to replace with a function but luckily we have lambdas for that kind of thing and I didn't using this one but this that this is the after for that where rather than having a macro that works on the local variables I just rolled the local variables up into a little inline function class inside the function and then gave that some methods and then call the methods and that did the same job now my code here actually looks bigger than the original that was the original that's mine but that's because the original this is only half the original because the original this is CRC little they had an equally big CRC big which is big endian where they copy and pasted the little one changed a few lines of code and that was a big endian version so I managed to compress those two ball that all down together so this is my entire function and all the little big endian bits the difference is up here in these two lines so you can easily see above each other what the differences are rather than having to completely rambley functions at work very slightly different so this is a relation this is the adler crc in this one the this is very performance critical loop and again this is using loop unrolling and this is quite interesting because when I wrote it I wrote this processing methods I put in line now if you go to any compiler taught if you go to a big conference about super firstly compiler guys are getting up onstage and they're gonna go but compiler knows better than you you don't have to say in line the compiler will make them far better judgment of whether something should be in line than you ever will in your whole life well in this case of hidden because when I when I when I wrote this my performance went fell off a cliff and until I actually use this force in line which is actually the juice macro that maps to whatever compiler specific attribute used to actually force of functions being lined when I put that back everything goes back to normal but it wasn't in lining this stuff but when you make when you force it to do its job properly the promise is just as good as it was with with the old original macros just doing the stuff in line these were more challenging to replace these were these macros they were used inside that 800 line switch statement note the go-to down there these were particularly nasty because they mutate both the local variables in the function they're being used in by name and variables in in the in the class as well so for these I had to resort to lambdas which actually works out to be very a very elegant way to do so these would go rather than having global macros with with with name with names like load that will never conflict you know no one else is going to use a macro called restore are they ever battle there's no danger of that being a problem so so rotten that we keep all the skeptical and these had some of the lambda functions inside this inside the function that was using it and this is actually all the stuff on the previous slide and some more and and by capturing by reference the local variables and then using and then also using member variables we can do all the stuff that these these guys were doing but without having to resort to nasty C to Gary the go-to I ended up using an exception which annoys me immensely so instead of they were using go to to get to the end of this big state machine and I couldn't find another way from inside a lambda to sort of just jump out of many levels of scoped indirection so end up with a macro which is a tiny performance hit and I if I if I had more time I think I could probably come up with a better way of doing that whole state machine that would avoid that altogether so yeah maybe it maybe as I hangover task one day I'll I'll fix that a lot of what I've done so far has just been fine grained tweaking but the most important thing when you're reviewing real code is spotting the hidden patterns in there which could be more clearly represented by the program itself so for example something I noticed was that they were they had a bunch of scattered functions and variables and macros that seemed to be collectively managing a FIFO of bits so when you spot this kind of thing it's always important to try and pull it all together and I ended up pulling so this is an example of where I pulled all of them all of their bit their FIFO bit five functionality together into one class called it output FIFO which is like dead and there's some useful member variables and this when you do this it also it labels it makes it clear see to you as the user that as a coder that this this is a concept so when you start spotting ways that this is used around the code base you can start to see other patterns so I noticed that all over the all over the codebase they were they were they were they had explicit bits of code like this where they would write an integer as four bytes by bit shifting and they do it all over the place so I replaced that with a function like writes int MSB which made all all of the rest of the code get much cleaner there's also code where there are write some sequences of bytes so over here they write the same thing the same thing multiple times so in order to be able to write an equivalent which is like this where we just have one line that takes a whole sequence I used some Super Plus 14 11 14 goodness with a very alec template that can take any number of arguments so writing this once makes the rest of the code much cleaner so in a kind of recursive way to be meta there's this kind of exercise of looking for patterns in the code and then replacing those patterns with one instance which you reuse and with a single copy of whatever it is whether whether that's an operation a bunch of things you do at the same time it's kind of its kind of the same thing that Jesus itself is doing because that's looking patterns and replacing with a token we're doing the same and if you keep compressing compressing the entropy is going to go up as well as collected together behavior into nicely named functions you can also collect together variables into nicely related classes so they had a structure here which defines some parameters of compressions so and so some I don't know what of these things do there's there the kind of parameters that they use when they're looking for the block chains and they but they weren't really using this all of the once they got this configuration structure and all the values in it would just be passed around as integers separately all over the codebase so I made the points of going through and taking my version but I would always pass this as a by value type so that group of variables moved around together so if we if we had some settings in one of the classes that about the compression type it wasn't just bunch of integers copied from here it was one of these if you want to set it you set it if you want to return that you return the whole thing and the overhead is nothing for this and it really helps manage the complexity of what you're working on and it's it's doing that that's kind of thing as a counter for the sort of bit rot you get when people start adding to an existing project especially when you get big projects with lots of people working on it like this probably was so when people don't feel confident changing the code they tend to make very small changes so someone might add an integer because they need it to do what they're doing but they very rarely go back and actually refactor the whole thing because there's now too many integers they very rarely go and wrap those up into a structure so it's a kind of bit rot in the occasion you need to you need to be harsh on yourself when you're writing stuff but also when you're reviewing to say actually you know come on can we structure this better can we pack things together into into blocks that make more sense and have more of a concepts around them there's a Boy Scout motto that you always leave a place tidier than when you arrived even if that means picking up someone else's litter so I spent a couple of days forensic the fighting all this stuff so was it worth all that strain on my tendons um this is this is the 10,000 foot view of the end result that's the original and this is gun in my 3,000 line version it's still a couple of little constants probably leave them in I don't think I'd be very helpful to remove those this is the code size and so this is the compass is the this is the the code with the whitespace removed and the same thing compressed and this is my code with the whitespace removed and that's my code compressed I'm very happy with the size interesting Lee the entropy I was hoping to say I might doesn't compress very well at all whereas the original you know compresses because there's so much redundancy in that actually the reverse was true and I think that's because the original had all this constant data in that but also because actually mine has longer variable names and is it's a bit more regular so I know I was disappointed about that but very happy with the with the the code size at the end I 3300 lines it could probably get down sir 2500 I'm guessing with a bit more a bit more TLC the performance I was really hoping to go and mine is twice as fast it's exactly the same which it which it which is a win which is a win because it doesn't use it it doesn't use a lot of the tricks that usually woman was using to get performance so I was just really relieved actually you could buy us these it by changing the benchmark you could probably bias I could have cheated I could have changed a benchmark in a way that makes mine look a little bit better but it depends entirely what you feed the thing with but just the Reece rate don't write to me about this this is not science this is made-up rubbish it's not these not official stats meaningless so are there any is there any point for a user in what I've done there's a few I mean it's Heather's own being headers only is really useful because it makes it so much easier to use this kind of stuff being much smaller will probably reduce blows in somebody's application the actual API becomes better just by having stronger types and if I really was going to press on with this which I might do then refactoring it into a different API because I was just copying the original IP I wasn't trying to change that you could you can actually make it much more modern you could use streams that kind of change would ripple through the whole the whole code base and probably simplify things more internally what point am I trying to make probably just provide though I don't know it's a few random thoughts better code is better for its own sake surely you know given a bit more time what what I ended up with could end up being a really slick implementation of the algorithm and eventually I'd like to pop it introduced as a replacement for Zed Lib even though nobody would know the difference but I kind of know I know it was in there I'd feel field slightly slightly happier at night but if there's really any point I'm trying to make its we should be we should all be on the lookout for anything that can be improved even if you don't understand what it is you're looking at I mean I didn't I don't know really how was this compression algorithm works but I could still make it much easier for other people to come along and try to understand what it does something else that I thought was important was thing it is thank you this is actually a really good exercise if you're a beginner I would really recommend doing get this code it will pick some easier bit of code and just refactor it just go through look at read books on good C++ style and modern technique and just taking this obviously a bit rubbish and just go through and see what you can do with it because actually doing that is really good practice and it gets you into the habit of thinking oh I'm not satisfied with this come on you know you'll do it you'll do you'll do a pass you'll improve something and then look the step back again and go okay what else can I do and once you're in the habit of thinking that you'll think that wall you're writing new code and your code will be better first so around obviously after this I'm gonna get people saying well can we look at the friend finished code and yeah I was going to post a github URL or something but then I thought I think what copyright do I put at the top because the original is under a permissive license but it's like if you take a car and replace the wheels and then you replace the bodywork and then the engine and then the seats at one point is it not the original car so I think what I'll do is I'll I'll keep bashing aways it until there's really nothing of the original left because the one the one thing I really didn't quite get time to get rid of this damn state machines so I think that could be really nicely well rewritten using lambdas and cascading lambdas that return lambdas and could be a lovely state machine design with that so I might do that and then when it's definitely all my code i'll propo that introduced or or make it and make it public and that's my talk thank you very much if you were going to explain to a noob how one practically goes about this factoring code what the workflow is like what would you say I would say change small things incrementally you'd you sit down you look at you look through it you find something that's obviously wrong you fix it you try it you make sure the stuff still works you find another thing you can do this incrementally and as you're doing it you'll start with the obvious things and then as you're as you're reading the code you'll get a better picture for what it does and then you'll start to see your thing actually I see what it does now but maybe it could have been done better architectural II in a different way so the bigger the bigger changes come later just get in there and pick the obvious stuff you know fix the fix the layout replace the tabs in spaces do the you know replace some names that don't look very obvious if you look at a name and go oh what's that do replace it figure out what it does replace it and then you're finding you just come if you just sit there you'll come up with more and more things to do so for example replacing names find a replace or manually reading through the code finding every instance of it understanding it right I would be I think you'd be brave to do a global finder to replace on the name I mean unless it's a really unusual name yep so after you get the changes did it work first time I had a couple of places along the way where I broke it back because I was running my bench mount unit test there all the time I spotted that so you need unit tests if you're gonna be research for danger of making these changes isn't it yeah yeah obviously I mean obviously only an idiot would do this because the only thing I could possibly do to this code is break it because it already worked perfectly well that's why this is a pointless stunt you mentioned that you'd like to eventually have all of your own code in there what do you make of a comparison between refactoring a complicated thing like I said Lib and actually just starting fresh in writing it from scratch if you know how the algorithm itself works then yes stuff from scratch and rewrite said that writes it writing yourself that's probably a better way but I don't know how said that I still don't understand properly how it works but I can I know I can keep iterating on this until it becomes something really nice and probably by that point I will understand how it works and then until late yeah thanks I was just wondering if you can comment on sort of the proactive approach which is where you're gonna write this thing from the start bit bit to move on from that question and and how much you design before writing and how you know where you find the balance between putting all your effort into the design so that the code writing is essentially the easy bit or you know where's the balance and the trade-off in them my my in my humble experience over the years you never get even if you sit with a piece of paper and a whiteboard for weeks you'll never get it right first time whatever you come up with you're gonna end up refactoring so quite often it's best to just do it do a minimal Viable Product that works you know don't don't use tabs don't do anything really obviously silly but you can always come back and reflex when you should be coming back and looking what you've done anyway and then you know I look back at stuff I wrote a couple of years ago and find that embarrassing so if you ever gets the point where you're looking back on code you've written and not seeing mistakes in it you should be worried because that means that you either are either on the way down in your career or or you're so good that your codes utterly unimprovable and at which point you should even just yeah I don't know what happens when that happens I get one last question here what would you say would be the criteria of writing stuff is head of only four heads only the criteria well I mean it's got to be concise enough for that you know it's not too much for people to include but you in terms of what you should pay out and pay attention to make sure you keep things as as much private as possible don't don't put too much public too many public definitions in there make sure that the attack space for a user who's using this is as small as possible because it's very easy in the head is only if you think has only and your implementation is right there next to the definitions it's very easy to have things in there that you need which you accidentally make public but they really shouldn't because you only ever uses internally so to be very aware of scoping and private and keeping things private where you can make it you
Info
Channel: JUCE
Views: 11,698
Rating: undefined out of 5
Keywords: JUCE, Julian Storer, Zlib, C++, JUCE Summit, Coding standards, Compression
Id: SIAAvv1O7Gg
Channel Id: undefined
Length: 42min 54sec (2574 seconds)
Published: Wed Feb 10 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.