I took a real-world task where, at the end of a backtest, I needed to calculate the duration of all positions. I stored the open and close times of the positions in an array. Then I ran the following script on it.
In tasks like this, you only need to go through all the positions once, so I wasn’t able to gain any performance benefit from caching. I suppose the only thing that might help here is table data hard-coded into the programme before compilation. But it’s probably not worth fighting for half a millisecond. Thanks for the research!
P.S. Thanks to you, I’ve spotted a mistake in my own code.
I took a real-world task where, at the end of a backtest, I needed to calculate the duration of all positions. I stored the open and close times of the positions in an array. Then I ran the following script on it.
The attached file "Time.bin" contains 324,865 positions, of which 324,425(99.87%)have a short duration < 24 hours (does not span weekends or holidays).
For an objective comparison, increase the ratio of positions with a longer duration, and you will see a real increase in performance thanks to my optimizations.
The attached file ‘Time.bin’ contains 324,865 entries, of which 324,425(99.87 per cent) are of short duration (< 24 hours) (excluding weekends and public holidays).
For an objective comparison, increase the proportion of entries with longer durations, and you will see a real improvement in efficiency thanks to my optimisations.
Unfortunately, while running a date/time simulation, I found that none of the faster replacements for StructToTime() and TimeToStruct() posted before here and here worked correctly for years beyond 2100.
I had to revise the implementations to fix the issue so they now work correctly for all years.
In addition, significant performance improvements were achieved (thanks to some micro-optimizations, such as the use of unsigned division and modulus).
MQL's StructToTime() alternative:
datetimeStructToTimeFast(constMqlDateTime& st)
{
constuint j = st.mon < 3;
constuint y = st.year - j;
constuint m = j ? st.mon + 12 : st.mon;
constuint f = (979 * m - 2918) / 32; // days before monthconstuint n = st.day + f + 365*y + (y/4) - (y/100) + (y/400) - 306 - 719163;
return (datetime)n*86400LL + st.hour*3600 + st.min*60 + st.sec;
}
MQL's TimeToStruct() replacement:
boolTimeToStructFast(datetime time, MqlDateTime& dt_struct)
{
uint n = (uint)(time / 86400ULL) ; // Unix dayuint N = n + 12699422 ; // Computational calendar dayuint a = 4 * N + 3 ; // N_1uint c = a / 146097 ; // centuryuint e = a % 146097 / 4 ; // [0, 36524] - dayOfCenturyuint b = 4 * e + 3 ; // N_2uint z = b / 1461 ; // [0, 99] - yearOfCenturyuint h = b % 1461 / 4 ; // [0, 365] - Days since 1 Marchuint d = 2141 * h + 197913 ; // N_3uint M = d / 65536 ; // [3, 14] - Monthuint D = d % 65536 / 2141 ; // [0, 30] - Dayuint Y = 100 * c + z ; // Yearuint J = h >= 306 ; // JanFebuint l = z ? (z % 4 == 0) : (c % 4 == 0) ; // isLeapuint sec = (uint)(time - n * 86400ULL);
dt_struct.year = (int)(Y - 32800 + J);
dt_struct.mon = (int)(J ? M - 12 : M);
dt_struct.day = (int)(D + 1);
dt_struct.hour = (int)(sec / 3600);
dt_struct.min = (int)((sec / 60) % 60);
dt_struct.sec = (int)(sec % 60);
dt_struct.day_of_week = (int)((n + 4) % 7);
dt_struct.day_of_year = (int)(h + (J ? -306 : 59 + l));
return (true);
}
The discussion revolves around the performance of a function in different compiler versions and optimization settings. It highlights the variability in results due to compiler optimizations, the unreliability of certain benchmarks, and the impact of code modifications on performance. The author notes that the function's behavior is influenced by factors like the compiler version, optimization levels, and the presence of specific code elements, making it difficult to draw definitive conclusions. The function is considered unreliable and may be removed from benchmarks due to its inconsistent performance across different environments.
This is an algorithmic solution to the problem of handling alternating patterns that are disrupted by irregular events, such as leap years and century years. Beyond making the date conversion work correctly for all years, the approach demonstrates a general technique that can be reused to solve similar problems involving otherwise regular sequences with periodic exceptions.
The underlying idea is useful for financial markets – Trading cycles that follow regular business days but skip weekends and market holidays.
Sometimes I can open or close a trade.
I believe that 5 out of 6 of the results below are correct.
I believe that 5 out of 6 of the results below are correct.
Correction:
Result:
Correction:
Yes, it matches now.
I took a real-world task where, at the end of a backtest, I needed to calculate the duration of all positions. I stored the open and close times of the positions in an array. Then I ran the following script on it.
In tasks like this, you only need to go through all the positions once, so I wasn’t able to gain any performance benefit from caching. I suppose the only thing that might help here is table data hard-coded into the programme before compilation. But it’s probably not worth fighting for half a millisecond. Thanks for the research!
P.S. Thanks to you, I’ve spotted a mistake in my own code.
Thanks again.I took a real-world task where, at the end of a backtest, I needed to calculate the duration of all positions. I stored the open and close times of the positions in an array. Then I ran the following script on it.
The attached file "Time.bin" contains 324,865 positions, of which 324,425 (99.87%) have a short duration < 24 hours (does not span weekends or holidays).
For an objective comparison, increase the ratio of positions with a longer duration, and you will see a real increase in performance thanks to my optimizations.
The attached file ‘Time.bin’ contains 324,865 entries, of which 324,425 (99.87 per cent) are of short duration (< 24 hours) (excluding weekends and public holidays).
For an objective comparison, increase the proportion of entries with longer durations, and you will see a real improvement in efficiency thanks to my optimisations.
The result.
The larger this operand, the faster the cached version is.
P.S. Thanks to you, I’ve spotted a mistake in my own code.
Thanks again.Test:
Good day,
Unfortunately, while running a date/time simulation, I found that none of the faster replacements for StructToTime() and TimeToStruct() posted before here and here worked correctly for years beyond 2100.
I had to revise the implementations to fix the issue so they now work correctly for all years.
In addition, significant performance improvements were achieved (thanks to some micro-optimizations, such as the use of unsigned division and modulus).
MQL's StructToTime() alternative:
MQL's TimeToStruct() replacement:
Benchmarks:
did not work properly for the years after 2100
I’m sorry, but it’s 2026 now, and by 2100 there will most likely be no trace of the MT5 terminal left on the internet.
What’s the point of all this?
What’s the point of all this?
High-performance time functions valid for the full MQL5 datetime range (1/1/1970 to 31/12/3000):
(Derived from the Neri–Schneider calendar conversion algorithm: here)
The attached script file contains the source codes + complete validations.