WWDC2001 Session 618

Transcript

Kind: captions Language: en good afternoon it's good to see so many people here I've checked out of their hotels looking for a nice cool dark place to catch some rest before they take their flight back to wherever it is they came from have you guys caught all the other web objects sessions this week get some good sessions who cut who cuts deep Haman's presentation come on Damon and then we had James Dempsey's singing right okay well are there any Canadians in the room yeah well I'm not Canadian I'm from New Orleans Louisiana and I'm not gonna sing or play the guitar or anything we're gonna talk about some really interesting stuff about web objects now that came up to me yesterday and he said Fitz what is that makes web objects the an application server better than all the other application servers out there I said how should I know Bob you're the product manager thank you for your jaded applause anyway we're going to talk about making your web objects applications faster we have a couple of goals we're gonna find and eliminate performance bottlenecks in your components in your application in your enterprise object model we're going to talk about three areas we're going to talk about the tools needed to identify trouble spots including tools that ship with web objects we're going to talk about certain types of bottlenecks to look for in your web objects application and then we're going to talk about certain techniques which you can use from the get-go that will eliminate bottlenecks we're going to talk about when to do performance tuning do you do it now do you do it later do you wait till you finish your app do you start from the beginning we're going to talk about some tools that ship with web objects that make things a lot easier playback low events whoa stats other methods to measuring performance of your app we're going to discuss specifically web objects and uof techniques to improve your performance there's a lot of other techniques out there which we're not going to focus on related to programming and in general but those are for definitely another session and last when it's time to upgrade your hardware when it's time to get more RAM in that machine when it's time to get more processors when it's time to increase your processors fortunately webobjects I'm sorry increase the number of machines you have app servers fortunately web objects makes it really easy to add machines to your server farm now I'm a big fan of Donald Knuth you know I used to be a big law tech fan about eight or nine years ago every else should use lot tech you know way back you know in the old days when XML wasn't even the cool buzzword yet premature optimization is the root of all evil now I put this in here specifically because that is one of the things that I am most guilty of when I sit down we get a design for application we start coding and I just want everything to be really pretty we've got a nice clean slate I want it to be fast I want to make sure I don't do anything that is a performance bottleneck unfortunately that's not the time nor the place for doing that kind of work you want to work the cords functional stability you have a specification you create your application you want to get functionally stable before you start optimizing things because you never know when you're going to add or remove functionality you may opt Imai something that doesn't even wind up in your final application you may optimize something that is buried in a myriad of other heavy-duty methods and it turns out that it was just a waste of your time you don't want to sacrifice good design and maintainability for optimizing you don't want you don't want to wind up loosing everything into a single method that that's three hundred and seventy five thousand lines long just because it goes ten milliseconds faster on your little performance meter speed is not everything optimization is about making your application faster but making your development time just as fast it's also about maintainability another thing I'll talk about is a big carpenter adage which is measure twice cut once if you know I usually cut my finger first but you want to measure modify and then measure again so create a controlled environment this is really important can create a controlled environment do a measurement make a change that you think might be an improvement run your control test again with no other change in it and then you can get conclusive in from evidence as to what helps and what hinders our technology Fame works provides a number of different very handy things to help you measure your performance well event profiles methods in your components it's extremely precise method for measuring what parts in your application take more time well there's also whoa stats what stats is a very very enlightening thing to have on your application you could pull that up and tell it a quick look on one page what what methods I mean sorry what components are faster what components are slower you can see mean time you can see in this photo at the slowest access or the fastest access tells you a lot about what your components are doing the playback manager can simulate multiple users you set an NS user default in the command line run your application with the recording enabled and then when you quit the application then you can playback this session with one user simulate n use to simulate 200 users hammering your application lastly and one of my personal favorites is sequel debugging we all know that AOF create generates sequel to talk to your database I'm really happy to say that I haven't put a line of sequel in an application since I started using web objects and that was one of the things that it really made my life hell before I discovered this technology this shows you exactly all the sequel that web objects generates and sends to your database as well as information about what web objects gets back what objects gets back commit messages it gets back it says the beginning internal transaction finishing internal transaction will tell you how many rows it gets back it'll tell you when it's committed changes to your database so before we get started measuring and testing we need to come up with a test environment so you want to have your test environment mirror your deployment environment if your deployment environment is to Sun Enterprise 10 thousands with 64 processors and 4 terabytes of RAM you don't want to make your test system an old g3 that you found in the back closet with about 32 megabytes of RAM running you know something completely different you want to over the same operating system if you're deploying on Solaris test on Solaris if you're deploying on Mac OS 10 test on Mac os10 don't switch and change don't switch and modify and change your environment and midstream you want to try temp the mirror the number and kinds of servers now this is something that is is a little little difficult to do especially for really large scale deployments if you've got a if you've got a half a million dollars where the big iron you're running your deployment on you obviously can't afford that for your test environment however what you want to do is try mirrored as closely as possible try a particular scaled-down test environment of your deployment environment and lastly you want to isolate the test environment from your users you don't want to have your test environment running in the same segment of your land as your production environment you don't want them to share in the same database for example and I've seen that I've seen that happen where a test environment used the same database as the production environment you're not going to get you have so many variables other than what you're testing you're not going to get any conclusive results at all now so we've had we've got us a test environment set up we've gone up and bought no more hardware now we're gonna travel webpages are important you have an application with 20 30 40 100 pages make a list of the pages what pages are going to be frequented every time someone comes into the app for example your main page that's something you should work at to make blisteringly fast because first impressions are paramount when a user comes in and they see your applications front page takes half a minute to load no matter how fast the rest of the app is they're still gonna be left with that initial thought like god I got here and it took me half an hour to get the first page established acceptance criteria what you want to do is decide what is acceptable an acceptable speed for my application if you decide that you want every page to return in half a second well then work to meet that goal if you want every page to return in a minute and your users will put up with that and not go elsewhere well that's a goal to work for too you might want to work on a big query page so you have a query page that returns thousands of objects or raw roads as we'll discuss later on maybe that should return in five seconds there's certain cases where a longer wait is acceptable decide how many users you want to support concurrently is this application a small data entry app for a small company where you're going to have 20 or 30 people working on it a week or is it a large online store or an online presence where you're going to have hundreds of users hitting the app at the same time determine what you want to test for next create test cases which exercise the important pages Chris is going to give us a little demo of using well playback and then checking with most ads and more events to see with a speed of certain pages so you might want to create specific isolated cases for certain pages that are critical to your app ok now we're talking about preparing your test cases enabling recording for your application the whoa recording path path so if you want you have your application you've finished you finished your feature complete you're ready to do a little bit of optimization you set the command-line argument well recording path you set it to a directory in our case we use temp /foo rec this is our directory where web the web obvious application will write out a series of transactions requests in response at which records you're visiting the app manual executes a test case set up that variable set up that NS user default in your application launch the application execute the text face case stop the application now you can repeat this with different directories for each for each test case you can point the the wall recording path at different directories and say this test case is going to test the big fetch page this is going to test the main page this is going to test a user simulated user walking through the application finding something and then going back to another part to purchase something for example now when you run your test cases so now that we've enabled that user default we're going to pull that off of the command line and we're gonna run the app like we would run it in deployment now there's certain defaults that you're going to want to enable and or disable when you run when you deploy your application first is whoa caching enable low caching enabled allows which is which default to know is what allows you to do rapid development on your application it allows you to make changes to your dot wide and your dot HTML files save them and reload that in your browser and see it immediately by setting this to yes web objects knows that it's safe to cache these templates in memory so you'll get a small hit the first time web object reads the templates off the disk but it will cache them next time it will just follow a pointer a reference I'm sorry in memory to retrieve that information low debugging enabled you want to set that to no especially most especially if you use will application dot debug string that's a great method to use you can put tons of debugging print statements in your application which you'll see in your console and then when you deploy kick this over to know and go your merry way you'll want to see any of those you'll still see log strings you still see print lines and whatnot but it'll turn those off for you last but not least and it's something that I want to say with a little bit of a caveat is low allows current request handling that defaults to know now with this enables if you turn this on is multi-threading in your application this can provide a dramatic speed-up but I strongly strongly encourage you to be familiar with the caveats of multi-threaded programming before you turn this on in my experience multi-threading bugs are extremely difficult to track down and believe me it's something that you don't want to don't wind up working with if you're not familiar with multi-threading programming for programming so now that we've got all that set up we're going to disable the recording start more than one instance if you're looking at a large deployment start one instance if you're looking at a small deployment whatever your test environment is run the playback run one playback concurrently to run one at a time running serially let the system achieve steady state now this is very important you have to remember that your application contains it's the contains information contains methods that start and stop a new session is created and it lives for a certain period of time and dies the session death and birth are something that's very important to your application because your application is going to run all day 24/7 so what you want to do is let it reach a point where sessions are expiring and new sessions are being created so it'll create a sort of a steady receive a sort of a steady state so we've run our application we've done our playback we recording we've done our playback now we're going to take a look and see what kind of information we can find out about this application first we're going to look at a couple of the couple of pages we have low stats and well events set up now these are direct actions they are out-of-the-box now disabled you need to set a password for them to use them at all which we've done in our sample app and the low stats is something you just go to at any point after you set the app and it's going to give you this aggregate data it's collected about your application on a component level now a component as we know can be as big as a page as small as a character so they'll give you information on all of those you might want to pay attention to the the page ones about want to potentially pay attention to a certain sub component that's taken a lot of time configure event recording now event recording is something you need to go in and turn on there's several different buttons you can set say these are the kind of events I want you to gather information about web objects can amass an incredible amount of events in a second I don't even remember what the number is maybe and cue any one of the guys from engineering can say but it's blisteringly fast and has a very little effect on your application so you go to event setup say tell me what these events are do your playback and then you can come back and look at the wall event display page to see sub transaction times all the way down to the method granular level now for those of you who have been around doing web objects work since the old days when we use that other language anyway there were tools available for you called G prof G Mon you'd have to build your app in profile mode you'd have to run your application you'd have to quit your application you have to run it through another program and you get this really nice information that told you about this well that's really great but this is something that's something that you had to prepare for it to sit out it was very time-consuming this is something that happens on the fly in the product out of the box so we've done that now we can use whoa stats to find the pages that don't meet our acceptance criteria maybe we found a page that takes 10 seconds well let's look into why what's taking so long in that page is it a method that's very expensive is it a fetch to the database is it a multiple fetch to the database well event display after you find out what pages are giving you trouble can tell you what methods in that page are giving you trouble who's taking the most time in your application you can evaluate and you should evaluate the times relative to the total time that your application is running pay attention to what is used the most if you have a page that's hit once a day in the corner and it's really expensive and it takes 20 minutes you might not want to dedicate resources to fixing that page you may instead wants to dedicate resources to pick the two making the front page faster or the query that everyone does now I'm going to ask Chris miner senior consulting engineer with Apple eye services to come up and give us a demo about using wool recording and playback Chris so we need the guest one so we're gonna skip the recording portion because we did that earlier but just to show you what that looks like as a result use the the world recording path and we created this as a result of going through our application in a typical usage fashion we ended up with this recording and inside here are a number of files you can see the request and response is making up transactions so this only has a a transaction or excuse me nine transactions in it and then we'll just look at what one of the contents of one of these and you may be able to tell from that that it's a typical HTTP request it's just recording the request that came in from the browser that the app got and then afterwards it records the response that sends out so that should look a lot like an HTML page so then I've already got this application running actually it's this one here sorry and then from a command-line I'm just going to start up our our playback where it's going to read from that directory send each of the requests to the application and then compare the result with what it gets back this time so we can see up here that it's going along doing some logging to show you that it's actually hitting the app in this case we only have one playback going and we have only one application instance and down here you can see the some of the results and the information that's coming back for us so you can see that it's got perhaps the requests that will go through 0 through 8 and then it starts over so the next one it would be a new session so each time it gets the initial request again that's going to the main page again and that's starting a new session and then you can see it's the transaction times let's stop that for a second over here this is the comparison of the bytes that it expected to get versus the bytes that it actually did get so that can in some respects you can tell if there's a real problem with your app maybe a defect of sorts if it's returning back something wildly different that might well be a an error page something dramatically different than what I've expected so let me start that running again and go have a look at the low stats information so get the login pages mentioned before by default this will come up if you haven't set up your app to allow you to log in here you can't there's an a command line option for that it's kind of a security feature and there's a lot of information in this page we're only interested today and part of it so I'll just go down to that bit this happens to be you can see here there's two major sections of component action statistics and the direct actions as you can see there are no component actions and that's because this app relies exclusively on direct actions we see here on the left the page names it doesn't give you anything that's at a subpage level in this view and then I'd like to point out these minimum and maximum times over here you can see that it's not terribly obviously on this Hardware because it's written fast but on my laptop it showed a dramatically different value for the Macs and for the men I mean this one's still pretty large but it just goes to show that maybe on the first hit first time you hit the the main direct action the default direct action it might take a lot longer for something to happen but then over time this average is going to go lower and lower and you can see there that the 0.01 versus the half a second [Applause] so another thing we should be able to see in here are what we just saw there is at our session timeouts very short I think we set it to about 15 seconds just to demonstrate this other feature which is the current active sessions versus the maximum so here we have a hundred and sixty three sessions created but our current active session this is only 68 it's likely to stay at 68 for a long time it might fluctuate going up or down one but it shows this apps essentially being driven in a steady state which is essentially what we want because otherwise information we'd get about CPU usage and information we get about RAM usage would be pretty much irrelevant so now go on to the well event display so here's the event logging that fits referred to we're just going to look at component events and then once you set up what events you're interested in you can actually display display those events in this case we're going to just reset this to get a fresh view so our playback is still running so this information still getting updated and you can see that for the component events there's the the pages and but it's also the sub page components as well there's a different sorting capabilities to show this these events in different ways so we'll group them by page and then we can see something like Oh perhaps that the add movie page takes what seems like an awful long time for the number of calls relative to anything else so if you were gonna get some some sort of speed increase you might look for something in here on an app wide basis something else that's worth noting is that if these times per call are below what your criteria is then you're pretty much done so this just tells you you don't have any performance tuning to do which is pretty much the case in this application but you can drill down in here and see where the the cost of rendering a component comes from so at the bottom of things we see the WD footer costs pretty much nothing so maybe I to turn my attention to the WD table element if I were going to look for a place to pick up some speed okay and that's it okay all right thank you now we're going to and now we've talked about ways of measuring their performance of your application we're going to talk about techniques for improving your app the speed of your application technique specific to web objects and the enterprise object framework now maybe we could review this week we talked about there were to enterprise object adapters available there were the JDBC adapter and the anyone else remember the nun adapter now the nun adapter is extremely fast there are absolutely zero round trips to the database and however it's not quite as useful as the JDBC adapter we want to reduce trips the database COF rights like as I said before this sequel and sends it to the database and the database sends back well data sometimes AOF will not do will ask the database for data in a not so intelligent manner we might say it might repeatedly ask the database for little bits of data that it could have just asked for all at once so to find out where these problems exist we turn on the user default yo adapter debug enable now for those of you who use print statements in your application to see what some value of something is where some sort of where some sort of value changes or where your you are and the currently in the request response loop you'll see a number of print statements go by on your console when you turn on yo at the after debug enabled you are gonna see more stuff in your console than you ever knew to do with your gonna see when yo F first logs in your database you're gonna see every round-trip thereafter tons and tons and tons of fun things to look through now when you look at this at this information that you have tells you perhaps you'll see that there's multiple round trips for your database for one for one request response at loop maybe you're only maybe you're fetching for our example those of you who are familiar with the movies database you know I'm not creative enough to come up with like you know like election results and stuff like that so I grab the movie database it ships it's in a Java business logic examples you know it's tried and true when I fetch movies and then perhaps I navigate some of these faults one at a time as each vault fires it might make a separate trip to the database and it's extremely inefficient because we all know that each round-trip to database is pretty expensive so we're gonna talk about ways that you can optimize that one is to use batch faulting teleo after that when you fire off one fault go get a whole bunch more we're gonna use pre-fit we can use prefetching teleo f when you fetch these entities I want you to fetch these relationships at the same time just because we're gonna be using them pretty soon we could use a shared editing context this was a recent addition to web objects last year fantastic people were already doing this putting in editing context in their application and talking to it this is a really intelligent editing context that has relations to each editing context in the session you could put reference data into the shared editing context fetch it when your application starts up and never fetch it again or well there's a little detail that won't go too into right now but it will refresh your data eventually so if you have a will pop up containing all the cities that your company may service or I will pop up containing something like all the products that in your product line that's something that's doesn't change or changes very infrequently it might be a great candidate for shared editing context make your app read-only this is extremely fast if you have an application a scenario for example where you have a back-office application where users enter data where they change data where they delete data and then front application for your users where they just come and look at things it's sort of a reference application you can actually go ahead and put everything in the shared editing context and your application will rarely have to go back to the database for anything not only is extremely fast but it's extremely memory efficient because you don't have all these duplicate copies remember each editing context that contains an object has another copy of that object for very good reason mind you but when there's situations where you can avoid that you sure they would want to last you want to record a voice of a friend's data certainly the shared editing context takes care of that for us another thing we can do is reduce the amount of data that we get from the database you can use raw rose for non object data and very fetches raro czar yeah as you'll see there are big speed improvement on your on just a standard fetch because they fetch the information in to EOF just as always the information stretch in the database columns and rows put into a dictionary but instead of taking the next step in creating your enterprise objects objects with the business logic built into them you just get this raw data just straight attributes there's a cake there's occasions where it's very convenient to have that you stretch limits or don't allow unrestricted searches right now I have to say right now that my favorite search in now there is Google you know you go to that I find obscure error messages I type the error message into Google when it comes back with a page with the answer on it you know I mean anybody else does this cough or something you know is anybody still awake out there my goodness shouldn't eat in that big big lunches it only gives you you can search for the word Apple and you get hundreds of thousands of respond it'll say found four bajillion pages and it's only going to show you 200 incorrect that encourages you as a user to refine your search maybe you want to look for Apple Computer Apple Computer G for Apple Computer G for with a cinema display maybe I'll optimize your programming experience don't allow unrestricted searches make the user make the user enter some sort of criteria now this isn't always necessary if you have a company with 50 employees and they had search on last name search on first name sure let them hit return let them get all 50 employees and surf around to the heart's content to work for a big company that has 200,000 employees this might not work so well an unrestricted search might allow them to fetch your whole database at which point your DBA is gonna come hunt you down and kill you and then you're also going to run a memory in your machine so now I'm gonna go ahead and give you a little demo of some of the that demo some of the things that we we did here so let's see we should have two different screens coming up shortly now those of you either of you have been to the web object object sessions this week you guys have probably seen some really cool demos some really cool graphics you saw XM elementary you know we got movie mechanics you know I have to confess when I finish writing this demo yesterday at about 11:30 it looked like you know w3c consortium around like 1994 you know a gray background with the big jars across we handed all this stuff over to Matt for like a lot of you know Matt furling who really made this stuff look great let's hear it for Matt so okay so what I have here is an applicants application called movie mechanics which I've already cranked up and done some fun stuff with so I'm going to stop it for starters and yeah I didn't even mean that and now we're going to start the application again and when it decides to start up there it goes we have a couple of different defaults that I've set up one here in fact I could probably still go ahead and take a look at this thing here let's see optimization like that right Association targets yeah anyone resize oh it's way down here hiding right there we go okay you'll see I'm said I got you adapter debug enable - yes I've got it set to Worldport 1729 because I'm hitting it from this machine over here and then we'll auto open in browser know I'm not a big fan of the auto opening browser thing so let's go back to where we were so the application is launched here and you'll see it says welcome application gives you this URL and some other information and the first thing it tells you here is connecting with dictionary okay it's connected to our database it began an internal transactions fetched five rows okay now the first example we're going to do here is our shared editing context say it showed me share it at it in context example okay we're gonna go take a shared editing context using objects we'll share that in context versus using objects that we're just going to straight fetch from the database so as you see we have those five objects so if I click on this alright you notice up here no change no change didn't touch the database didn't do anything funny so let's find out how long that to it that took point oh three seconds now tell you a little bit about how this timers working okay I've written some just some simple Java timestamp methods in the awake of my page component I put on one out of the light better come back over here I put on the page component in the awake method I do a timestamp I get the current time and I save that and then at the very end of my opinion response they have another component that merely takes to the current time at that point and then gets the Delta between that in the start time and then squirrel's it away for me to put in this little clock here so now what we're gonna do is go ahead and do a regular fetch you'll notice touch the database five rows were processed it's not a how long that took it'll make a liar out I mean this is actually happening didn't just hard code these values so this machine there's a really fast machine and like my laptop in fact if I look out there I do see a couple of titanium laptops yeah I'd like one of those let's talk about what these do the shared editing context fetches the date at the beginning at the beginning of your application when your application starts round trip to the database it's way fast and it's great for reference data the regular fetch is just a plain old fetch and it requires at the least a round-trip to the database and as you can see there's a lot faster shared editing context again this is basically following a point a reference and the regular fetch talks the database so now we move on to something a little more interesting batch fetching and pre faulting so let me see it can see that clap or make a noise who's used the batch fetching and prefault in here that's falling in prefetching okay so we're gonna have some people who already know the answer to this right so we have three ways of getting the state note we do a regular fetch now the way this component works is I'm fetching all movies out of the movies database all 88 of them and then I'm iterating through the movies and I'm touching the roles relationship each movie has a role indiana jones for example has harrison for has the role of indiana jones in the role of marion whatnot I'm triggering that fault for each movie so integrating pup pup pup pup pup triggering those faults now we have a regular fetch which it just goes through that does the fetch and then triggers those false we have batch faulting on which sets the the batch faulting on the rolls relationship to 25 so that tells us is that when you fetch these bunch of movies and you navigate to to this particular relationship go ahead and get some extra stuff while you're there you know you're running to the grocery to pick up milk pick up some butter you know suppose it's stick of butter and loaf of milk both a part of a bread and a gallon of milk pick up some other stuff while you're there because it's likely we're going to need this and last but not least prefetching which is a very particular thing which says when we fetch the movies I want you to prefetch these certain attributes of the movies while you're there okay so I don't we at least three license regular fetch batch faulting prefetching who thinks the regular fetch is gonna be fastest anyone next mark who thinks batch faulting is going to be the fastest comes a little racier anyone think batch faulting you all know that prefetch is at the bottom so it's the fastest I don't think free fetch is gonna be the fastest all right okay so let's let's see what's gonna happen here regular fetch look at that oh my god would you look at that every one of those big lines that's begin from begin internal transaction to commit internal transaction the round trip to the database now man I can't even that was a lot of round trips the database look at that 88 to be precise let's find out how long that took that took 7.0 four seconds now mind you on my laptop this takes like 20 seconds match faulting look at that now we saw we saw a good number of transactions go by here but they're a little different looking right there you see here this is some information I put in here whoa whoa it's still going what's it doing hello someone tell me get in this machine let's see what that comes out to okay so anyway here we have this this transaction here that fetches in this case 84 rows it fetches is a big or select statement select select the role where the movie ID is this or this or this or this so it comes back with a whole bunch more of these relationships on the first shot prefetching boom right back at you how many fetches was that to now look at the difference from that a regular fetch were your fault thing you're doing multiple round trips with Avis many many many round trips the database 7 seconds here two point twenty three seconds for batch faulting in point 52 seconds for prefetching now here's something that's a little that's interesting about this some people out there might be saying well she's of course the first one slowest because then you'd fetch the ball in and in sleep in this component I'm in validating all objects in my editing context which pretty much wipes everything clean and makes the AF do everything all over again so we'll try this again just to show you that there's nothing funny going on here it's actually going to the database again each time it's gonna be a little faster because certain things are didn't happy and whatnot so batch fetching two point forty seconds this time and last but not least of prefetching 39 seconds point 39 seconds let's talk a little more about them regular fetch one round tip to the database for each vault fired can be extremely inefficient very very time-consuming batch faulting its defining the relationship in question now this is a difference between batch faulting and prefetching batch faulting you can define that programmatically or an ill modeler per relationship you define it once a neo modeler and your applications use your model and they just go their merry way and it just happens to many relationships only you can't do batch faulting on a to one relationship this fetches again the next n objects whenever a fault is fired so for example in this demo we set batch faulting across the roles relationship to 25 so it fetches one it faults in one relationship and it gets the next 25 last is prefetching it's used on a fresh specification so you have to consciously go in when you create a new fetch and say I want you to prefetch these things when I when you get the movie I want you to prefetch the director and I want you to prefetch the roles or and you can prefetch multiple relationships it adds only one round-trip to the original fast fetch it it's very very very fast so enough of that we'll move on to probably another one of my favorites raw rose now raw Rose and objects I just kind of blew it I hit the button already so what I'm selecting here all the movie roles in database I wanted something with more data obviously I don't have that much data in this database the difference is seemingly small when you have a small amount of data but when you have a lot of data the difference is really really big so okay I just fetched the raw Rose inadvertently and let's take a look and see what the time was on that 0.08 seconds now I'm gonna fetch the object objects now raw Rose fetches the precious rose out of the database every column in the row and in this case I'm fetching every column in the row you can write sequel and only fetch certain columns if you wish you could fetch the primary key and maybe the title of something but in this case I've fetched everything sort and gave me back a bunch of dictionaries objects I fetch the I fetched an information in the database you get get all attributes for each object and they're wrapped in enterprise objects and boom you have your enterprise objects so let's see how fast that goes point 13 seconds now we'll click it a couple times here to sort of let things uh normalize out and see what the difference is the difference it's kind of it depends you'll see different speeds but in the most part it tends to come up to about 50% or so speed improvement depending if you tweak out your raro fetch you can see a really really huge improvement now there is a fantastic fantastic article that I used for reference on this on stepwise written by Malcolm Crawford and I think he's sitting right there that tells you in great great deal Thank You mouths yeah there you go there you go Malcolm as we all know has done us a number of good services this week let's talk a little more let's talk a little more about what these do rah rah rah Rose don't instantiate enterprise objects you just get back dictionaries key value title Indiana Jones director George Lucas it was Lucas wasn't it music John Williams okay it's very fast it doesn't have to select all columns objects is just a plain old fetch it creates objects for all the EOS it fetches and it can be slow for very large fetches especially when you're dealing with tens of thousands of objects so I'm gonna I'm not gonna take a look at well events set up right now but I will really quickly see if I can hit on low stats and see what it tells me about this application of mine that I was running okay so here we are we have be nice and share which is my little shared editing context demo with an average time it's that's basically pretty fast because even the non-shared part is only fetching a little bit of data there's the venerable main round trips round trips is where we did the different kinds of fetching batch faulting and prefetching look at that the max is 7.2 you see that that was the FET that was a round trip where we went and batch and we single faulted everything in and last but not least raw rose which was basically pretty fast cuz again we're just fetching the object single fetch as you can see we fetched 450 rolls still that was very fast and I just kicked something over here and so it was very fast because we just fat did one round-trip to the database so so that's buddy let's get back to the slides now thank you okay you know we I had to get a Star Trek token but I'm not a big Star Trek Voyager fan you know so I went with the classic right lazy instantiation I took a programming web objects to class at I took a program about these two classes that at Apple in fact it took programming objects one but programming web objects two was taught by Kyle Christensen it was absolutely fantastic teacher anyone had time for teacher oh it was the greatest class I didn't fall asleep once a I said something to me that just absolutely killed me he said when you're when you're programming he says you want to cook your steak until it's smoking and then ten seconds less and I said Kyle what the hell does that mean he said he says you want to wait to the absolute last second to do something if you don't have to do it don't do it because it may turn out you know 20 feet away from here you don't have to do it use the lazy instantiation this is an example here we have Shatner's ego which is going to take a long time to get because it's really big as we all know so the first time it's called it checks the sense this private instance variable to say is this not if it's null it goes ahead fetches it squirrel's it away in the instance variable for the next time someone comes through and then returns it huge bonus it's a great little trick to use back to EOF stuff subclass yo generic record instead of via custom object a generic record has a couple of little tweaks to the cute it was a key value coding the way it stores the information for the attributes of your EO it's blistering fast especially in web objects v absolutely incredible what they've done with this don't overwrite now another thing that your generic record does as well is by default deferred fault is a deferred faulting or shared faulting deferred faulting the first fall thing is enabled now whenever let's let's say we fetch a movie okay and it has several attributes it has roll it has a link to director woody used to do in the old days back in the 1990's we used to create a fault for each one of these attributes now if you're now a movie you'd say it has ten possible faults we fetch a thousand movies okay so we've just had to create a thousand movie objects plus ten thousand fault objects now the generic record by default creates one shared fault for all for all these different faults that's incredible speed up because you don't have to create all these additional objects even though the fault objects were small next and this well this one seemed a little bit obviously but I've seen some people do some weird stuff don't override value for key key value coding one of my greatest friends in the web objects framework is a patented key value coding as we all know and we know that self or pets are evil as well don't override that key value value for key and take value for key are called incredibly often in enterprise objects in your whoa components and they're optimized to to be as fast as possible something you don't want to over Ryde certainly if you're debugging you want to put something in their print statement but make sure you rip that whole thing out when you're done we have object specific stuff we can synchronize bindings by hand we have synchronizes variables with bindings which is still nowhere near as long as add objects to both sides of relationship with key we have synchronizes variables with bindings which in well component by defaults returns true now this is one of the things that really blew my mind when someone explained it to me they said when you synchronize when you go through the request responsive if you put a simple string in your page it's going to print the title of a movie or or something or you have your own sub component let's say it's custom sub component it takes in a name or something we all know the request response loop big fans of the request response loop awake take valuation request invoke action a pendant response and sleep okay those three middle ones take values request invoke action dependent response there's a lot of stuff going on there and one of the things that goes on in those three methods are variable synchronization from component parent component the child component what that means is that take values gets call boom synchronize pass pass the value into the chocolate pull it back out do it again invoke action pass it in and pull it out do it again and append response pass it in pull it out that's like six method calls there if you have a sub component that you're using everywhere say a button bar component that just has some buttons on it that you want to pull some information down from the parent floor say it's just a footer and we can talk about and we'll talk about a way if he was making that footer faster in a moment and you just need a little bit of information from the page you might want to say look web objects don't synchronize these variables for me but instead I'm going to take care of it myself and then in the appropriate method of the three above and I mentioned you can pull or push off that value that you need now if you want to talk even faster we could talk about using stateless components now stateless component whenever our components instantiated you get a new component you say you know page with name boom new component you put a component into a into a page when that page gets instantiated that sub component boom gets instantiated if you say that components stateless web objects knows that this the component that's not going to change based on session or based on something a user's done it's a stateless component it loads it up once and it reuses it over and over and over again so if you have 700 users on your website and you have that little footer that is the big legal disclaimer in it make that stateless and you don't have 700 of those lying around you have one not only is it faster but you use less memory now in the end here is sort of thrown a couple little misc miscellaneous things some of which aren't necessarily related to web objects but session timeout Chris showed you before we had our session timeout set to 15 seconds you know that's pretty extreme but you might want to see what the typical user experiences in your application when a session times out you get that that memory is it can is available to the garbage collector to be picked up eventually so that that means that when your session gets bigger bigger bigger they can squish it back down a little more fetch outside the request response loop if a loser logs in then you need to get some data base on that user but you don't need it right away in that first page you might want to do a delayed action to fetch that or to put it in sleep or or somewhere outside that somewhere somewhere safe to put it outside this and the users not going to be waiting in dextra database I'm a big fan of getting someone else to do this for me you can notice a market improvement especially if you're just using single attribute primary keys which is what we all know and love with the enterprise subjects framework offload images and Static data to another server if you've got an application that's serving up I just experienced this recently QuickTime VR is 300 400 kilobyte DRS and you've got 200,000 of these things well you don't want your same web server as your app that's serving up your web app to be serving up these images you might want have an additional web server the arse dot your company comm images that your company comm have that serve up the static images and the arse and sound files and God knows what check your HTML check the HTML this is wow this is like really obvious to me but now but wasn't obvious to me at the time I had a page that we designed for this client of our with all these nested tables and you know and it looked just the way they want it and I was like oh thank god that's over with and then we hit the page and it just took forever to render it took forever this was back in like you know years ago 1999 I think check the HTML see if you can't optimize your HTML see if it's actually compliant run HTML run a linting program over it make sure it's it's valid HTML remove extraneous tables do as much as you can with as little as you can and last but not least there's just Java there's Java performance tuning things like optimize it or J probe I believe optimize it is currently available on Mac OS 10 now lastly but not leastly we'll talk a little bit about what we learned we talked about determining where the bottlenecks line measure modify measure remember again in a controlled environment change only one thing we talked about web objects and EOF techniques we have batch faulting prefetching we have synchronizing bindings we're not synchronizing bindings stateless components that sort of thing general programming techniques lazy instantiation upgrade your hardware huge thing right here you know if if you're running application and you're hitting swap in a deployment environment you're doomed there's nothing that you can sit down and optimize and improve that second that your machines were not a rain'll and oftentimes you'll discover that hardware is a lot cheaper than developer manpower so with that I want to let you know that if you hurry up please don't run the web objects lab is open for another 20 minutes downstairs in room K the only session left web objects track is the feedback forum which is going to start at 3:30 and there's your contact information which ensures all new to you you