Performance issues |
Post Reply |
Author | ||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
Posted: 16 November 2006 at 5:11pm |
|||
The calendar control was running pretty fast for me until I started trying to populate it with data. Once I start populating it with my database everything slows to a crawl.
I knew the problem wasn't with the database since pulling from the cache was at almost the same speed.
I don't know that I have found the source of the problem, but, with a profiler I found something very interesting. Pulling up events and recurrence patterns by ID from the cache is a VERY costly maneuver. This means that petty looking calls to get the master event for a recurrence pattern or vice versa are actually HUGE time wasters.
Is there a reason that the event and recurrence structures can't store pointers to each other to identify this master/pattern relationship?
Also, when I run without debugging I get an 80-90% increase in the speed of the calendar. I don't know how to account for this since I doubt the rest of the program sees such a boost.
|
||||
sserge
Moderator Group Joined: 01 December 2004 Status: Offline Points: 1297 |
Post Options
Thanks(0)
|
|||
MFC Arrays accessor methods are implemented with heavy usage of #defines and traces in debug mode. Speed increase could be 10 up to times -- what can you see here. |
||||
sserge
Moderator Group Joined: 01 December 2004 Status: Offline Points: 1297 |
Post Options
Thanks(0)
|
|||
And in addition -- custom Data Provider cache works now only for RetrieveDayEvents method. So if you call somewhere GetEvent(id) or GetRecurrencePattern(id) -- those calls will not be cached and always read from the DB. Actually we recently fixed this behavior for the next version and if you need an immediate update - go to support area.
Also you can implement cache on application side . Just 2 maps: ID --> Object. On read return from cache, on update - update both DB and cache. -- WBR, Serge |
||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
|
|||
I'm looking into some things here to help reduce the problem. The profiler shows that huge portions of time are spent cloning events. Since the events are cloned every time GetRecurrencePattern or GetMasterEvent are called this is where basically all of the time goes. This could potentially account for up to 50% of the slowdown.
Do I HAVE to clone to clone the event before returning it in an override? Why don't you just hash this from the cache and return it? It makes no sense to me to be returning a pointer, but then to return it as a pointer to a clone (I.E. impossible to modify the base structure, but no const specifier to show this.)
|
||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
|
|||
Incedentally, the reason that cloning takes so much longer for me than it does in the samples is because I construct a couple of additional objects with my special CalendarEvent and CalendarRecurrence classes. Each of these extra objects constructs 2-8 COleDateTime objects, another non trivial task. This isn't a big deal unless we start creating tons and tons of new CalendarEvent objects (which we do in this cloning process.)
I'd like to reduce the overall amount of cloning that happens in here but I don't know what is safe and what isn't. I assume that you clone these things for a reason but it seems pointless most of the time.
|
||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
|
|||
I have this working fast enough without the debugger to be excusable, however, I can't hold the arrow keys to scroll because the key repeat rate is faster than the rate at which each day can be populated, not to mention weeks. This is true with or without the debugger.
My main question at this point is whether or not it is possible to get similar speeds with the debugger attached. I still see a 90% increase by not attaching the debugger, even though I am still using the debug build. (I.E. Ctrl+F5 runs the calendar 9 times faster than F5.)
Since I have to be able to use the application to debug it, this performance drop is a serious issue. It takes 15 seconds to load a month for calendar display, and another 15 seconds every time it has to redraw the buffer.
If it looks like I have a clue what is going on with this, don't be decieved. I am totally lost about what to do here. This slow down is so major (~2-3% of normal speed WITHOUT the debugger attached, ~0.2% with) that I have to believe that there is more to this than meets the eye. If anyone else has seen any slowdown with this control for a wierd reason, I would love to find out what happened. Maybe it will give me a clue as to how to resolve this.
|
||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
|
|||
EUREKA!!!!!
MUCH better. I can now hold down the arrow key to scroll left or right outside of debug mode. As it turns out, the constructor was at fault all the way.
Since the calendar does so much cloning calendar events and such get allocated and deallocated with little concern for what that means. Since I added a half dozen COleDateTime objects to the mix it became really slow. The only way to speed it back up is to put the extra stuff in a hash and use the Event/Pattern ID as the key for the hash.
This really needs to be documented. If users need to, they can add a LITTLE to a private implementation of the CXTPCalendarEvent and CXTPRecurrencePattern types, but if they have to add very much, they should put whatever is possible into a hash table to avoid all of the cloning and stuff underneath.
Of course, the best solution would be for the number of calls to CreateNewEvent, CloneEvent, CloneEventTo, Clear, and the recurrence pattern counterparts to be reduced underneath . Any chance of this? The potential speed increase is at least 50%. This looks almost critical for anything but a plain vanilla memory provider calendar.
I still have a 90% discrepancy between when the debugger is and isn't attached however...
|
||||
sserge
Moderator Group Joined: 01 December 2004 Status: Offline Points: 1297 |
Post Options
Thanks(0)
|
|||
About clones...
For the next version we also made some optimization in data provider and recurrence events processing. Amount of Clone calles is also reduced and performance is improved in 3-7 times. Cache is the search tree and some event properties (start/end times) are critical. Event placement in a tree depends on those properties. To change events ChangeEvent method must be used. Also for recurrence events some not so easy relations are updated. And if we will return reference and somebody change event/recurrence properties the data provider may work not in the right way and this will be hard to find. To avoid such problems data provider clones all returned events. This may be not so fast, but easy to use. Clone object in memory (without reading DB) is fast enough and problem generally comes from higher program layers. About speed in the debugger... Which VC do you use (6.0, 2002, 2003, 2005) ? I've seen such a low speed only when build and run with profiler (like DevParthner tools). Try to disable profiler and test. The difference should be quite significant. Also how many events do you have for each day, and how many exceptions your recurrence events have ? -- WBR, Serge |
||||
JohnCrenshaw
Groupie Joined: 08 September 2006 Status: Offline Points: 65 |
Post Options
Thanks(0)
|
|||
Well, sort of, the problem comes from higher layers, but mostly because TON'S of extra stuff is being stored in there. Largely my fault, but the amount of cloning took something that would have been acceptable over the top. I have done some optimizing on my end to bring it within acceptable parameters, I haven't heavily tested any speed improvements in 10.4 yet.
VC 2005 W/O team suite. Your samples are within acceptable opperation parameters even with the debugger, however, my code isn't. In a release build without the debugger I can get away with it, but repainting takes a long time, longer than it should, and this makes drag based opperations clunky.
since I don't have team suite, I don't get a profiler ( stupid somebody at MS, I still don't know who to blame for requiring the purchase of a full team suite for a simple critical development tool.) I have a 3rd party profiler that I can attach at runtime but I have to do it manually whenever I want profiling. In short, profiler is always off.
Not many, sometimes only a couple (makes me wonder where the time is going if not many events exist to get cloned. Perhaps I need to pull out that profiler again.)
Anyway, thanks for the responsivenes and help on this. It's nice to not be stranded when things go wrong.
|
||||
Post Reply | |
Tweet
|
Forum Jump | Forum Permissions You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |