Bug 247912 - Slow performance related to use of KHolidays in KDE 4.5
Summary: Slow performance related to use of KHolidays in KDE 4.5
Status: RESOLVED FIXED
Alias: None
Product: kmymoney
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: KMyMoney Devel Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-15 03:48 UTC by Alvaro Soliverez
Modified: 2010-08-16 01:15 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alvaro Soliverez 2010-08-15 03:48:34 UTC
Version:           unspecified (using KDE 4.5.0) 
OS:                Linux

Under KDE 4.5, KMyMoney is terribly slow when starting or using anything that requires a call to isProcessingDay().
Going to Schedule settings and setting the region to none solves the performance problem, but the real problem lies in the way KHoliday calculates the holidays when isHoliday() is called.


Reproducible: Didn't try


Actual Results:  
slow performance when using schedules with holidays

Expected Results:  
it should work fast

Here is some info by John Layt on the HolidayRegion class:

isHoliday() is fairly inefficient as every time you call it with a single date, it recalculates all the holidays in that year for every calendar system and then checks the requested day. There is no caching or intelligence in what it calculates. I have some optimisations planned but those will be in 4.6. KHoliday also uses QList rather than a QHash, but that's something I can't change.

My suggestion would be if you have a date range you need to check to instead call this HolidayRegion method:

Holiday::List holidays( const QDate &startDate, const QDate &endDate ) const;

This will only calculate the holidays in a year once for the entire date range and return you a list of all the holidays in the date range. You can then iterate over the list to check your dates, or perhaps hash them, which should be quicker. The code for isHoliday() does it like this:

bool HolidayRegion::isHoliday( const QDate &date ) const

{

Holiday::List holidayList = holidays( date );

if ( holidayList.count() > 0 ) {

foreach ( const KHolidays::Holiday &holiday, holidayList ) {

if ( holiday.dayType() == Holiday::NonWorkday ) {

return true;

}

}

}

return false;

}

As for memory usage, the HolidayRegion does cache the contents of the holiday file in a QByteArray to save repeatedly reading the file from disk, but a single file is only about 2k. Unfortunately it doesn't use QSharedData so having multiple HolidayRegions around for the same country will have multiple copies of the file.
Comment 1 Alvaro Soliverez 2010-08-15 04:03:18 UTC
I consider this blocking for release, since the workaround is not obvious, and it takes over 2 minutes and 600MB of RAM to load a file. People will think KMM has hung on loading.
Comment 2 Alvaro Soliverez 2010-08-15 15:58:49 UTC
SVN commit 1163993 by asoliverez:

Added a cache to store the holidays for the next 2 years, which works around the slow performance of HolidayRegion class.

BUG:247912

 M  +55 -3     kmymoney.cpp  
 M  +5 -0      kmymoney.h  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1163993
Comment 3 Alvaro Soliverez 2010-08-15 17:27:27 UTC
SVN commit 1164020 by asoliverez:

Added a check for pre KDE 4.5

BUG:247912

 M  +7 -0      kmymoney.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1164020
Comment 4 Jack 2010-08-15 23:41:44 UTC
cmake, compile, and run OK for me on both KDE 4.4.5 (Gentoo) and KDE 4.5.0 (ArchLinux).  This is with US settings, have not tried any other holiday settings.
Comment 5 Alvaro Soliverez 2010-08-16 01:15:14 UTC
SVN commit 1164112 by asoliverez:

Removed incorrect break statement

BUG:247912

 M  +2 -4      kmymoney.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1164112