Performance Tips
CoordinateSharp is designed to be simple to use right "out-of-the-box". The library's eager loaded approach means
that developers can have access to multitudes of data with minimal code. Though this is incredibly convenient to use,
it sometimes comes at the cost of performance. Luckily, CoordinateSharp also has the ability increase performance by
allowing developers to turn off eager loading for properties their project may not use. This can greatly increase
performance and reduce overhead with just a few extra lines a code.
What is Eager Loading?
To understand how CoordinateSharp performance tweaks work, you should first understand
eager loading and how it relates to CoordinateSharp. Eager loading (opposite of lazy loading)
is basically when something pre-loads everything possible, even if it is not needed. A great example of this is a web page
that loads every single image, even if that part of the page isn't rendered. The cost of this is slower load times initially,
but the benefit is that "things" are ready and loaded once needed. If you are scrolling down a web-page and those images are already
loaded, you won't have any delay while you are scrolling.
CoordinateSharp takes advantage of this by running all calculations anytime a coordinate property or coordinate date is changed.
Let's say you want to change your latitude by 3 degrees. As soon as you change that latitude, CoordinateSharp will recalculate
its conversions and celestial information automatically. This can be super convenient, but can also cost you in performance.
These performance hits are usually minor and go unnoticed, but may become a factor once you start multi-threading, doing bulk conversions or throw constant updates at a Coordinate
object.
The first step to maximizing performance is to determine what you need from CoordinateSharp. If you only plan to use sunset and sunrise times
for example, then you should turn off all Lunar calculations and coordinate conversions. If you plan to only use it to convert Geodetic to UTM, then ensure that only
UTM is eagerloading.
Let's start with the basics.
In this example we turn eager loading completely off. The only thing that will take place is geodetic lat/long conversions (they cannot be turned off), but
all other conversions will cease until called.
//Create EagerLoad object with all properties set to false.
EagerLoad el = new EagerLoad(false);
//Create a new Coordinate Object at N 45, E 67 with a date time of now.
//Pass the EagerLoad object through the constructor.
Coordinate coord = new Coordinate(45,67, DateTime.Now, el);
The above example will give the maximum performance when initializing a Coordinate object. You will still be able to access
any geodetic properties (ex. Latitudinal seconds), but any other coordinate systems, or celestial calculations will not
be loaded. You still have the ability to load some properties on demand when ready however.
In this example we load our UTM and MGRS properties. once loaded we have access to current UTM and MGRS information.
coord.LoadUTM_MGRS_Info();
Usually, lazy loading like in the above example isn't needed. Rather, people normally just wish to turn off the calculations
for the properties they don't need.
The below example shows how to use the library if you only require ECEF conversions. All other calculations/conversion will not take place
(with the exception of geodetic). This will greatly increase performance.
//Create EagerLoad object with only ECEF set to load.
EagerLoad el = new EagerLoad(EagerLoadType.ECEF);
//Create a new Coordinate Object at N 45, E 67.
//Pass the EagerLoad object through the constructor.
Coordinate coord = new Coordinate(45, 67, el);
Console.WriteLine(coord.ECEF);//1765.163 km, 4158.464 km, 4487.348 km
It is important to note that properties not utilizing eager loading will be null, or not updated if eager loading is turned
off after Coordinate
creation. If you try to reference any non-loaded properties, you will either receive NullReference
exceptions or out-of-date information.
Eager Loading Options
Eager loading for the below properties may be turned off (Reference EagerLoad
).
Property |
Flag |
Celestial |
EagerLoad.Celestial |
Cartesian |
EagerLoad.Cartesian |
ECEF |
EagerLoad.ECEF |
UTM & MGRS |
EagerLoad.UTM_MGRS |
Web Mercator |
EagerLoad.WebMercator |
GEOREF |
EagerLoad.GEOREF |
You may access extensions properties for certain items as well. For example if you only need sunset times, you can turn
off lunar calculations only. The parent property must be set to eager load or else the extension settings will not
trigger.
Extension |
Flag |
Parent |
Notes |
Solar Cycle |
EagerLoad_ExtensionsType.Solar_Cycle |
Celestial |
Solar Rise & Set Times, Altitude & Azimuth |
Lunar Cycle |
EagerLoad_ExtensionsType.Lunar_Cycle |
Celestial |
Lunar Rise & Set Times, Altitude, Azimuth, Phase & Distance |
Solar Eclipse |
EagerLoad_ExtensionsType.Solar_Eclipse |
Celestial |
Solar Eclipse Data |
Lunar Eclipse |
EagerLoad_ExtensionsType.Lunar_Eclipse |
Celestial |
Lunar Eclipse Data |
Solstices / Equinoxes |
EagerLoad_ExtensionsType.Solstice_Equinox |
Celestial |
Solstice and Equinox data |
Zodiac |
EagerLoad_ExtensionsType.Zodiac |
Celestial |
Zodiac Information |
MGRS |
EagerLoad_ExtensionsType.MGRS |
UTM_MGRS |
MGRS Conversion (Relies on UTM) |
Examples
Below are examples that can boost performance in commonly used scenarios. This example can be modified to fit your use case.
Change Application Wide Default Eager Load Settings
//Turn off eager loading for all Coordinate objects unless specified
GlobalSettings.Default_EagerLoad = new EagerLoad(false);
Eager Load ECEF and Celestial Calculations Only
//Create EagerLoad object with multiple flags
EagerLoad el = new EagerLoad(EagerLoadType.ECEF | EagerLoadType.Celestial);
//Create Coordinate with eager load settings
Coordinate coord = new Coordinate(45.34, 65.47, DateTime.Now, el);
Parse a Coordinate String with Eager Loading Options
//Create EagerLoad object with multiple flags
EagerLoad el = new EagerLoad(EagerLoadType.ECEF);
//Parse string to coordinate with eager loading settings specified.
Coordinate coord;
Coordinate.TryParse("45.34, 65.47", el, out coord);
Eager Load Sun Cycle Times Only
//Create EagerLoad object with Celestial turned on
EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
//Set EagerLoad Extensions to load Sun Cycle only.
el.Extensions = new EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle);
//Create Coordinate with eager load settings
Coordinate coord = new Coordinate(45.34, 65.47, DateTime.Now, el);
Eager Load Sun Cycle in Local Time with a Celestial Object
//Create EagerLoad object with Celestial turned on
EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
//Set EagerLoad Extensions to load Sun Cycle only.
el.Extensions = new EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle);
//Create Local Time Celestial Object
double offset = -4;//UTC offset hours
Celestial cel = Celestial.CalculateCelestialTimes(45.34, 65.47, DateTime.Now, el, offset);
Eager Load UTM Only
//Create EagerLoad object with Celestial turned on
EagerLoad el = new EagerLoad(EagerLoadType.UTM_MGRS);
//Set all EagerLoad Extensions off as it will turn off MGRS, but leave UTM.
el.Extensions = new EagerLoad_Extensions(false);
//Create Coordinate with eager load settings
Coordinate coord = new Coordinate(45.34, 65.47, el);