 Cool. Thanks to you, Michael. Wonderful. Hopefully you can hear me. Excellent. This is what I'm going to say. So Let me not tell you that. Let's get straight into it. So I think We've done a huge amount of work on performance in collaboration line in the last year And it just be great to show you some of the things there but to do that we need to understand really how it's working So of course, you know, we build on those LibreOffice technology So on the on the server we have effectively a LibreOffice in a box and we're talking about the Secure Containment of that Earlier, it's very locked down box, but it's running there and that then streams tiles to the client as PNG images With with various smarts around that And the kit behaves in a different way to a normal LibreOffice So it's essentially fully zoomed out So you see a view you never see on your normal PC and it's your very small document There's a view of this giant a giant document there and that's very important so we can track when things change Because we cash a lot of things on the client to make it much more responsive So yeah, and then of course there are multiple views of that Which is very similar to creating a new window So in LibreOffice you can create multiple windows of your current document to get multiple views on it And we essentially reuse that code with a number of well changes Improvements around that all of which is built into the core On top of that then we have a demon that multiplexes messages from all of the users to many of these isolated kits and That's yeah, I mean there's another source of performance problems there potentially and say messages are sent from the kids The web service demon to sometimes a proxy and then to the the actual browser on the other end and Yeah, so useful to see how that works and then of course in the browser You have a relatively thin piece of JavaScript. I'm not not too much going on there But we do lots of things to try and make things quicker So we have overlays for cursors. So your curse of blinking is not causing any bandwidth You know to be used for wasted your selections or overlay is there as you pan and zoom We interpolate on the client so you get a very fluid a smooth Experience that so that's that's pretty much how it works when you understand that maybe you can Maybe you can get further, but of course if you understand JavaScript, you'll realize it's a garbage collected language for almost everything Which means that the people the right JavaScript forget that you need to free stuff and And so the few things that aren't garbage collected like timers They typically leak horribly. So, you know, they create a timer that's got a period of 10 milliseconds or something 50 milliseconds and they just leave it running forever And so often often it's very common experience as you use the web But you know the CPU of your browser process goes up and up and up until it You know your laptop just sits there warming the room and I think what carbon we could save if you know time has actually completed Probably everywhere and so on so we don't have big problems in in Collaborate online around that now I guess many of us are they used to freeing things having created them from a C++ world But certainly some of the integrations that we sit inside have embarrassing leaks of this time Why not primarily talking about the former of battery power and so on? Fundamentally talking about the responsiveness and so on. So let's look at the stuff That's actually happening in the LibreOffice core I think I talked about this before and one of the typical test methodologies of our users Is to load a document with eight people in and then just hammer the keyboard like you know with with two flippers And it turns out that you can do this, you know, ten times faster than a normal average typist And to be fair I can I can type, you know about three times As slow as just mashing the keyboard randomly, but arguably what I say is nonsense anyway So you know you're not winning but the real problem here is rendering the squiggly lines underneath for misspelled things And it turns out the misspelled rendering was Incredibly slower Than rendering well all the rest of the document really amazing like 90% of the CPU time during these red lines Which are the most beautifully crafted Anti-aliased, you know these splines with all these control points are sitting there and it turns out of course This is really slowing down LibreOffice as well You know if you have a large spreadsheet with lots of repeated names Or if you had a document with the wrong language set, which is quite common You know you get a lot of red lines squiggly everywhere And you know there's a real problem there. Luckily we've we fixed that of course that's upstream And we render a little bit of a red squiggle and then we we do put maps to cash that which Just disappears off the profile, which is encouraging One of the problems we had a particularly on our mobile version on android was the performance of Editing text shapes and press so so when you start to edit You know we would we would click To to select the text, you know, and that's just a tap And then you'd expect to get a keyboard and be able to well edit the text really But it was taking initially something like five seconds to to actually get the keyboard up During which time people had tapped a whole lot more and it's just unshippedly bad And and so one of the problems there was just setting up the property panels We just love to Pause some xml that describes the property panel create all of these, uh, you know little widgets Routinely relay them out continually while we're doing that and then throw them away again shortly afterwards Before then creating them again and often several times during the during the process of of changing context So I mean when you click in there The sidebar notionally changes that changes the context. So yeah, it's really really silly But but after that then just drawing the dashed line around the edit text box You know, we can see see one of those here Unfortunately, this was subdivided into whole series of lines Which were all rendered as one batch and so there's a lot of self intersection You know, if you ever drawn a doodle and colored in You know like colored it in as probably you're doing now while it's listening to me You know, it's actually quite expensive doing that winding Business of what lines and shapes overlap each other and do they intersect and when you create lots and lots and lots of dashes You have as well. It's really quite an expensive computational problem to work out if they intersect Um, but of course as you draw the line, you know, this is a nonsense. They didn't intersect at all So so on the dash line rendering arm in um Did some work for us to to short circuit this and accelerate the dash line rendering huge huge impact Practically we got rid of that but again It's it's not necessarily the thing you expect that takes the time rendering a slide You wouldn't think that it would be the dashed line around the text box But so it was and it isn't now Both in LibreOffice and in like a lateral line. Now, certainly the sidebar A couple of things there like you're just deferring setting up the sidebar until you actually need it It's helpful, but particularly caching the panels so that they're always there. They're just not necessarily visible So we hide them away at very small sizes And then we can just you know relay those out to to show that in a cached way Way quicker for all desktop users less flicker less cpu time. I'm just just a lot lot better Um, I guess I think actually that's all been redone recently for using native widgets So probably we'll have to re re look at that caching thing, but yeah You know, it's good to have native widgets. So and we're looking forward to shipping that in the next collateral line With much much prettier sidebar So jason jason So generating jason is is quite important for us in terms of Getting that sidebar to the client so that we can make this mobile phone one one handed user experience And yeah, so we then describe all these widgets each of which can describe itself in jason, which is great So we used to have this dump as property property tree method here And that would essentially create an abstract Tree structure thing this property tree p tree Um and for each one we'd create that but the problem is that each one contains its nested elements So we would just stack these things up inside each other allocating and freeing endlessly and incredibly inefficient Um for what is ultimately just streaming out a sequence of text Uh, so, you know, this this property tree thing turned out to be a Complete nightmare And so instead now we have a nice fast jason writer, which uses some of the optimized string streaming functionality We have in the LibreOffice core Um, so yeah, thanks again to knoll who's disappeared that from the profile, which is uh fantastic um image scaling and rendering Yeah, so well, uh lots of scaling for various reasons you can see here that uh, you know, this is a very very slow slow process and uh, you know, we do it several times we we scale it during some idle redraw or painting of the page completely draw and then also While while we're painting tiles And interestingly this whole piece here doesn't it doesn't need doing and We've been sure I think has removed that. Um, but one of the problems was that Though we had a very nice scaling cache. It wasn't really prepared for having multiple windows at different zoom levels Um, and so it wasn't for random reasons We had a window in the background It was a different resolution and so we continually rescaling images to render those take all nonsense So now, uh, you know, we scale and we cache Cache layers at multiple zoom levels. So as you zoom in and out in your pc LibreOffice, that's then quicker um, and of course we can um We actually extended that to to cache depending on the number of views you have because lots of different users can be at different zoom levels Uh, so that's that's great. And we will sure fix that. So hopefully lots of improvements there Um writer loves to uh very carefully count all of the areas. It's invalidated and you remember I said that you're seeing a whole writer document like it's a massive massive window Which is very very unusual to have a whole document if you think of a 300 page document all of it in view at the same time And so there's this this notional optimization that supposedly compresses regions by merging them together And uh, yeah The algorithm is pretty horrific. It's something like n cubed in the number of regions And if you consider a document lots of fields in it So like a bullet is a field And as you move into or out of a bullet region Often we you know invalidate all those bullets to render them with a gray field mark Um, so you can suddenly end up with well Thousands of items going through this n cubed loop Uh, which before you know, it is billions of operations Are doing doing stuff and yeah, so this is just a nonsense. So actually micklos did some great work here to not invalidate bullets and render them as you move into them because it's kind of a silly feature And again now we have this uh, it's only n squared. So that that's kind of nice And I think now this is uh worked with lubosha and there's some more kind of sorting and optimizing of that to make it even more efficient Which hopefully that will accelerate all large writer documents that are that are rendered Similarly in calc, um, we have this uh, well this get print area thing is called As you switch views for various reasons partly to work out where to draw Page boundaries I think so you can draw lines on that But calc is a particularly nasty problem. So the pixel area is dependent on zoom So you see as you zoom in it's very important that all your rows that are the same Notional print height are the same pixel height on the screen Um for two reasons probably the subclinical neurosis of of Spreadsheet workers means that it avoids them trying to resize it to make them all the same height on the screen And then as they zoom their different heights again I think there's an important aesthetic a thing though But it does mean that you have to scan from the beginning of the document To work out the pixel position of any cell Which is really expensive And there was a whole load of problems here that would essentially you're getting a row You know trying to work out which row you're at for a given height Is is important and well, it's now massively faster We have span trees for hidden rows and span trees for row heights and those can be non-contiguous and you know so now instead of uh kind of doing row by row checking of some of these we we intersect these span trees And work out optimal regions that match so we can go. Ah, yeah Well, these are all that height, but they're all hidden and then there's some more of that height that they're visible So that we can calculate The the pixel rounding problems that get compound as you get down and down and down larger sheets much more quickly so that's very useful for LibreOffice And there's a lot more in in core. I think Noel had a lot of good pointers on getting involved in performance I'm personally quite passionate about it I just get no time for it, but Noel's done a lot of things There are lots, you know faster file opening better font caching text rendering a faster scrolling You know spreadsheets improved spreadsheet filtering which should a lot of time Big chart insertion set up problems and so on and yeah I mean in LibreOffice kit Lubos has done some some great stuff We used to calculate and paint and lay out the whole document in order to render it to an invisible surface It's just like one by one pixels large And so avoiding lots of lots of that layouts overhead and rendering overhead That was just just not not useful. So I think at this point we get a detail overload There's really loads of stuff that's being fixed And all of that's shared LibreOffice helps improve our performance there and interestingly online renders is increasingly How every every modern tool kit should be rendering so in idle and validation rendering Rather than trying to do it immediately when you type the keys and so on and so hopefully lots of that helps improve the future You know as we move to a sort of a uniform skier chiro type rendering model My hope is that that's you know, it's not done immediately. It's done Ideally and so we can start to get rid of the back buffers and the Some of this other nonsense that we don't need And really you know reduce memory use improve performance and just integrate better with the underlying operating system So then there's the web services demon. Um, so we had some really silly things in there. So One of the things that it does is is it shuffles memory from the kit to the web services demon to the client And you know, we buffer our data obviously It's important that you know, we make messages and we store them in a standard vector And then we transmit them, you know from the beginning and we used to you know transmit a chunk And then erase it and that if you've got a lot of data 20 megabyte image, for example I mean shuffling all that data down, you know, and then it gets smaller and smaller, but not very quickly Um, so, you know, SSL will only allow you to write a 16 k chunk maximum So if you shuffle 10 megabytes down through a 16 k chunks you get 1200 Vector copies, uh, which is you know on average 10 10 megabytes Each copy which is really not fast. I'm particularly on a mobile phone or device there I'm so well, anyway, we inserted a buffer class that wraps this and we don't erase we have a we have an offset there and well There you go I'm so we shuffled in a megabyte at a time instead of 16 k at a time and well You're 64 times faster, which is very very visible Another problem with stl on android is just it's just amazing. I mean, you know When you first use and compiles lead profits for android it turned out we had to binary patch all sorts of bits of You know actual core stl library out The bottom which is really embarrassing. So, you know, they're just live runtime bugs and would make the profits not even start So I don't think we have to binary patch those anymore But I think the assembler to do it is still in there to kind of mend android Sort of very basic so we could start But this you know destroying vectors should not be On the profile I mean like you should not have a loop that assigns all of these items to zero It should you know, well, but but here you are here. You can see it. I mean you you don't believe me I didn't believe it either But here we are, you know, sort of creating and destroying these buffers And it's not even in the memory allocation subsystem particularly. It's you know, it's like clearing Clearing a vector shouldn't you know, like shouldn't be taking time you can see When you destroy that you should anyway these are all vectors of char You know, they're just like white buffers and so so the vector madness on android is taking far longer than actually You know the scaling the bitmaps which we found out was problem And you know and rendering stuff kind of really silly. So anyway, we fixed that And then key events. So on a heavy load, you know, actually it turns out you can't process the key events quick enough so what you really need to be doing is Merge together the tool that's done some great work here to you know turn your Into a single foo input to try and collapse that backlog And to you know, because there's a whole load of things as you insert text There's a lot of work that's done in the document I mean as you switch context and song that there's work done and so so we can then catch up much much more effectively And similarly for removing text context, which is kind of a backspace delete event merging loads together And I don't know actually if we merge These things into each other, but probably we should be doing that too So it would be nice if someone wants to hack on, you know, kind of optimizing that before it goes in there in the queue Just to shrink the input queue Another huge win was the previously we had to pause all of our document editing during save And upload so LibreOffice save is usually pretty quick We've done lots of work to optimize that at least for reasonably sized documents. It's you know Way sub second and very very flash Which is cool But the upload which we assumed would be fast, you know Like in in the same data center from one machine to another machine sending a 10 megabyte document from autosave It turns out this can take several seconds Um, just just sending that committing it makes sure it's saved to an object storage Which can be you know some some big cluster of of magic machines and so on and this is not something that's been optimized in terms of end to end Round trip, you know an atomic transaction time because usually that's not not a problem for enterprise passing can share You know like there's plenty of time to do your upload and background synchronization So thanks to ash we've done a whole load of work in the core to Allow us to do that asynchronously so that the saving is going on and you don't stall your typing So, you know, there isn't a a jerk while you're typing That is just streaming out and committing in the background and that that's Quite a complex piece of work and that arrived in six four eleven And well six or ten Maybe in six four nine six four somewhere there anyway There's been a lot of work to make that really really robust and catch lots of corner cases And you know when things are happening asynchronously and your save is going on while you're closing You know doing another edit and closing the document There's lots of interactions there that are really worth getting right and testing and tracking and so on So even say there are some synchronous things there So if you're renaming for example, it's very important But we've actually done the rename And switched to the new document before allowing you to type again So Pedro has made some beautiful animations for for this and for the core piece where we can't make it asynchronous yet There we have a plan for that. There's a nice animation there as you as you save your document, which is kind of cool So javascript. Yes, I told you about javascript earlier Turns out that we thought that most of our performance problems either in the network or in the web service demon or in LibreOffice, but actually Found that we'd been really Misfocusing our optimization lots of the performance problems really in the javascript and in the browser, which is really unexpected And we found one of these and then then Tor and some that made a beautiful end-to-end profiler So in view we can see our stuff going. Well as Tor finds out, it's not quite end-to-end like when you press a key press It's hard to trace that through the pieces and back again, but Well, anyway Yeah, so so but but at least it shows you everything that's going on in a synchronized way And you can turn that on and then you can see, you know an event happening in the browser being sent being received being processed and tiles coming coming back That's that's that's really useful and Yeah, be careful with your javascript. It turns out there's a whole lot of silly things So so one of the things that was particularly annoying was that you could see tiles render one by one So, you know, if you did something you would you know if you look in a profile You could actually see things like that. So as you get paged down And a new part of the spreadsheet was revealed, you know, you'd actually see tile artifacts, which is Which is kind of awful and it turns out this is actually a feature So so we were unaware of the fact it was a feature But it seems that we were sending web socket messages one by one to get them down the pipe as quickly as possible And the browser is processing web socket messages one by one by one by one And in between it re-renders everything So, you know as you would as you would get your tile the new image it would essentially re-render I mean it was creating a video for you of what was going on Exactly what we don't want because of course while it was doing that it was blocking Any other input coming and it was actually buffering these things very aggressively So it's like a 128k buffer in in the background Both outbound and inbound on the web socket. And so it's just a bit ridiculous. So Um, there's a comment about it here, I guess. So what what do we do? Well, we had we had a sleep and everything gets much quicker. Um, so so what we do is essentially we We read our web socket very quickly, uh, and we don't do anything with that message that will touch the DOM We don't Redraw or do anything. We just queue it all up. So we slip loads of content off the socket And uh, yeah, and in a millisecond later when we've you know read it all in Then we process it and render that on the screen. And so that was pretty cool that that made things a lot better um, and and you can see, uh, what can you see? What is this? Well Yeah, so so one of the other problems was that having done this We were all happy and everything but it still didn't seem quite as good as it could be And so asynchronous image loading turns out turns out that even if you have all of the image data In your hand as an image url And you want to create an image out of it. You can't do it You have to do it asynchronously because the browser was fed up with people, you know asking synchronous web requests at the slow and so there's Broadly no shortcut. It seems for well, I have all of the data. Please give me an image. It's again asynchronous so Anyhow, so once we put that in to then wait until the image actually was there Then uh, finally we could then get get this working So we then emit all of our events that are complete meaning, you know, we've got the image data Everything is in hand So we can render quickly and then suddenly, you know as you page down you you you get pretty much a whole screen full Which is kind of cool Another big problem we found was uh, just the gc pressure from loading A converting images So image formats are a bit of a problem And we we need to use image urls, which are base 64 encoded to get them in and well There was a whole load of string copying now. I mean essentially what we were doing was this we were doing, you know, appending A character to a string And then doing this base 64 Okay, and simple piece of code But it essentially piles up ever longer strings Which are then garbage collected by javascript and and this makes Just an incredible waste So instead it's much better if you pass all of those parameters as arguments to a function using a rather more magic javascript feature With this data And so which was great So implemented that and then we discovered that we blew the stack if we had particularly complex images So amazingly everything worked fine while you had a white document But when you had like white noise in your document You got a very large thing and you blow the javascript stack. So well Anyway, now we use uh, you know, we we only passed 4000 4k parameters to the function and amazingly faster and much less gc pressure And we love to repeat the work the same work the whole time So, you know, we get multiple cursor updates if you hold your your arrow down and calc You get several at a time and we would then just be scrolling and doing all this calculation Uh until we you know to process the queue. So well just delay those to the end I'm the table handling. We love to send continually send bogus table Messages about the table handles, you know for resizing and sizing tables So as you've typed in a table every character you send would create and destroy Loads of these these handles, you know, like half a second's worth of, you know Dom fooling around creating and handling those messages all of them jubica So well 15 times faster to do it just once You have about four minutes left. I'm uh, thank you. I have a timer here four minutes 38 seconds But thanks gillum. You're you're you're wonderful. And I'm getting there. I'm getting there So now we have a message is done event that just does all of this at the end when those all slurped Um, the jQuery plugin we discovered this actually from writing profiling tools Uh, so we we had a profiler Uh, so you can run the whole javascript editing session and you can run like Five or six random typers, which is our our bet noir as it were And we can run them all in parallel and see what's going on as we rushed it You know run it through the javascript cave And it turns out that there's some just, you know, cargo culting and a jQuery plugin to do something particularly unimportant Uh, but then was taking 800 milliseconds, of course with with the jastom. It took five seconds on on start-ups So you really saw it Um and mudfix that now so so our google, uh, our traditional, uh user experience with menus and toolbar Is then just massively faster to start now. Which is kind of good. So yeah Prefiling is good. So anyway, here are the conclusions. We're much faster We did a lot of work. Uh, lots of that is in LibreOffice 7 2 the core work more of it's coming in 7 3 A whole lot of it is already shipping in uh cool 6 4 11 But some of it is the more risky pieces in terms of Adjusting rendering and avoiding bits of invalidations coming in 2021 In the next month or so month or two There's a lot more work to be done here We're writing stressing and profiling tools that replay traces and load Load the code, uh, and yeah, we're not even nearly done yet I think there's a factor of two at least almost everywhere you look So, uh, yeah, so the real trick then is just knowing what to optimize now and looking at the profiles and focusing that work on On things so yeah, thank you for everyone that's done lots of hard work there And well it all drives our mission to make open source rock and uh, that's my tool any questions Thank you very much, Michael. Thank you. And I don't see any question on the chat like, uh People might be amazed at how uh, amazingly This performance has improved It's possible or they just be hitting their heads, you know, we we found a lot of really silly things there and you know Well, I don't know until you profile and you have time to uh, you know, look at these things You don't you don't catch the cities. So, you know, it's really it's really great to have Time and an economic incentive then to chase a performance and really improve that for everyone So maybe like one short question for me is it so you mentioned You had the complexity of a big of n3 at some point Yes, uh that you uh kind of shrank into uh big of n2 instead and does that apply to the desktop version as well? Yes, yes, absolutely. All right that stuff was um in the desktop now, of course It's the end there is the number of invalidation regions on the screen um Possibly see that if you have a large writer document well zoomed out and say lots of bullets and fields invalidations You know, it's easy to criticize programmers The reality is we're using the code in a way that they didn't expect it to And so, you know, it makes perfect sense to write an incubed algorithm if you have a small n, you know If it's 10, then there's not really a problem, but when it's 10 000 You have an epic problem. And so yeah, I mean you can't blame the code But you should improve prove that for everyone So yeah much of the work here is is in the core and gone back into it I think, you know the first third of my talk or or two thirds Two fifths was probably about that, you know