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.

How do I Boost Performance!


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);