Reputation: 353
I am trying to write a simple LINQ query in which DateTime is compared to get the results. My requirement is that the DateTime has to be compared only till milliseconds and hence I have to apply formatter. The query is as follows
var availableValues = from value in AvailableValues
where DateTime.Compare(DateTime.ParseExact(value.Time.ToString("dd/MM/yyyy HH:mm:ss.fff"), "dd/MM/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.CurrentCulture),
DateTime.ParseExact(currentTime.ToString("dd/MM/yyyy HH:mm:ss.fff"), "dd/MM/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.CurrentCulture)) == 0
select value;
AvailableValues
is huge collection and the above query is causing a perfomance hit.
It would be of great help if someone could suggest me a better way to achieve the expected result.
Upvotes: 1
Views: 1217
Reputation: 172200
My requirement is that the DateTime has to be compared only till milliseconds and hence I have to apply formatter.
Nope, you don't have to apply a formatter. Simply create a new date with an empty millisecond component. Instead of
DateTime.Compare(date1, date2)
use
DateTime.Compare(DropMilliseconds(date1), DropMilliseconds(date2))
or, since your are only interested in equality (not in the additional information that DateTime.Compare will give you):
DropMilliseconds(date1) == DropMilliseconds(date2)
with DropMilliseconds defined as follows (or any alternative implementation):
private static DateTime DropMilliseconds(DateTime dtm)
{
return new DateTime(dtm.Year, dtm.Month, dtm.Day,
dtm.Hour, dtm.Minute, dtm.Second,
dtm.Kind);
}
If you are worried about the method call overhead, you can tell the compiler to aggressively inline it.
Upvotes: 2
Reputation: 43876
Cache the value for the currentTime
to avoid recalculating it for every comparison
As far as I understand, you only want to compare including whole milliseconds (no fractions, no ticks). So you can create new DateTime
values with only whole ms like that (if your query provider allows that):
DateTime current = new DateTime(
currentTime.Year, currentTime.Month, currentTime.Day,
currenTime.Hour, currentTime.Minute, currentTime.Second, currentTime.Kind).
AddMilliseconds(currentTime.Millisecond);
var availableValues = from value in AvailableValues
where currentTime == new DateTime(
value.Time.Year, value.Time.Month, value.Time.Day,
value.Time.Hour, value.Time.Minute, value.Time.Second, value.Time.Kind).
AddMilliseconds(value.Time.Millisecond)
select value;
This should be a lot faster than converting your DateTime
s to string
and back again.
Upvotes: 3