Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache UTC offset #3898

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Cache UTC offset #3898

wants to merge 3 commits into from

Conversation

gzotti
Copy link
Member

@gzotti gzotti commented Sep 17, 2024

Finding UTC offset is surprisingly costly but is executed per-frame, shown in VTune. Caching the result per-minute saves at least part of it.

This needs some testing.

Description

Fixes # (issue)

Screenshots (if appropriate):

2024-09-16d getCommonInfoString_UTCoffset

With this caching:
2024-09-16e cachedUTCoffset

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • This change requires a documentation update
  • Housekeeping

How Has This Been Tested?

Test Configuration:

  • Operating system: Win11
  • Graphics Card: irrelevant

Checklist:

  • My code follows the code style of this project.
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (header file)
  • I have updated the respective chapter in the Stellarium User Guide
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

- avoid at least part of the costly operations
@gzotti gzotti added the enhancement Improve existing functionality label Sep 17, 2024
@gzotti gzotti added this to the 24.4 milestone Sep 17, 2024
@gzotti gzotti self-assigned this Sep 17, 2024
@gzotti gzotti marked this pull request as ready for review September 17, 2024 09:11
Copy link

Great PR! Please pay attention to the following items before merging:

Files matching src/**/*.cpp:

  • Are possibly unused includes removed?

This is an automatically generated QA checklist based on modified files.

double getUTCOffset(const double JD) const;
private:
// Cache is over qHash(&UTCOffsetHashData).
static QCache<size_t, qint64> utcOffsetCache;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why static?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I make this a per-object variable, it breaks many const-qualified functions. If there will ever be more than one core, they would just share the results. Or do you see problems with this?

Copy link
Contributor

@10110111 10110111 Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I make this a per-object variable, it breaks many const-qualified functions.

This is exactly why mutable keyword was introduced: one of the uses for it is implementation of transparent caches.

If there will ever be more than one core, they would just share the results.

Hmm, this doesn't seem like a likely situation, but in this way the staticness might make sense, though there's some strangeness in the way you implement the cache that I can't tell whether it actually makes sense.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I forgot about mutable.

qint64 shiftInSeconds = 0;
if (tzName=="system_default" || (loc.planetName=="Earth" && !tzValid && !QString("LMST LTST").contains(tzName)))
// Complete the cache object and hash it.
u.loc= & const_cast<StelLocation &>(loc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some ugliness here. Why do you keep the object by const reference and then violate this constness?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what various warnings made me do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is the wrong way to read the warnings then :P They are supposed to make you improve the code, not equip it with kludges.

StelUtils::getDateTimeFromJulianDay(JD, &year, &month, &day, &hour, &minute, &second);
// This method takes a significant amount of time. Try to cache a few entries.
// All these elements can influence UTCOffset, so we must include them in the cache.
// Presumably, offset does not change during a minute, so we can exclude seconds here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an unsafe assumption to me. What is the cost of keeping the seconds?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updates every second, not every minute.

@10110111
Copy link
Contributor

What is the performance benefit from this? Is it even measurable in any way except by using a profiler?

@gzotti
Copy link
Member Author

gzotti commented Sep 17, 2024

What is the performance benefit from this? Is it even measurable in any way except by using a profiler?

I just wondered what takes so long just displaying InfoText. The commonInfoString was a surprisingly costly part of it, and here this seemingly trivial UTC lookup appears to be far from trivial.

// Complete the cache object and hash it.
u.loc= & const_cast<StelLocation &>(loc);
u.tz = & const_cast<QTimeZone&>(tz);
size_t dateLocHash=qHash(&u);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you hashing a pointer to a local variable?..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did I misunderstand the qHash() docs? Does this only hash the pointer, not its contents?
OK, that's not what I wanted... :-o
Do I need to write my own qHash function for the struct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you need a custom hash function for every custom data type. This may be of help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve existing functionality
Development

Successfully merging this pull request may close these issues.

2 participants