我的解决方案域项目 (.NET Framework) 中有以下简单结构:
public struct Candlestick
{
public DateTime OpenTime;
public DateTime CloseTime;
public double Open;
public double High;
public double Low;
public double Close;
public double Volume;
}
在我的业务逻辑中,我有许多方法可以在大烛台结构列表中执行基于时间的搜索。例如:
public static int IndexOfFirst(this IReadOnlyList<Candlestick> data, DateTime from)
{
if (data == null)
throw new ArgumentNullException(nameof(data));
int count = data.Count;
if (count == 0) return -1;
int fromIdx = 0;
while (data[fromIdx].OpenTime < from)
{
if (++fromIdx == count)
{
return -1;
}
}
return fromIdx;
}
在 Candlestick 结构中使用 long (
Int64
) 类型作为时间变量通常是个好主意,以便逻辑层可以使用此结构更快地运行吗?此外,我的意思是将相应的类保留在应用程序级别(视图模型层中的 CandlestickVM),并使用 DateTime
. 类型的时间变量
为了检验我使用
Int64
的想法,我在 dotnetfiddle.net 上运行了一个简单的性能测试:
DateTime a = new DateTime(2023, 01, 01);
DateTime b = new DateTime(2023, 02, 01);
TimeSpan incr = new TimeSpan(1);
DateTime now = a;
Stopwatch sw = Stopwatch.StartNew();
while (now < b)
{
now += incr;
}
sw.Stop();
Console.WriteLine($"It took {sw.Elapsed} to run the Date & Time test.");
long incr2 = incr.Ticks;
long now2 = a.Ticks;
long bticks = b.Ticks;
sw.Restart();
while (now2 < bticks)
{
now2 += incr2;
}
sw.Stop();
Console.WriteLine($"It took {sw.Elapsed} to run the long test.");
结果如下:
It took 00:00:04.8027716 to run the Date & Time test.
It took 00:00:00.9261338 to run the long test.
您的代码仅使用
DateTime
进行比较,而您的基准测试则进行加法。我使用 BenchmarkDtonet 做了一个简单的基准测试,仅进行了比较,这里是代码和结果:
[SimpleJob(RuntimeMoniker.Net70)]
[RPlotExporter]
public class LongXDateTime
{
[Params(1_000_000)]
private int N;
private DateTime[] Da;
private DateTime[] Db;
private long[] La;
private long[] Lb;
[GlobalSetup]
public void Setup()
{
Da = new DateTime[N];
Db = new DateTime[N];
La = new long[N];
Lb = new long[N];
for (int i = 0; i < N; i++)
{
La[i] = Random.Shared.NextInt64(DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks);
Lb[i] = Random.Shared.NextInt64(DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks);
Da[i] = new DateTime(La[i]);
Db[i] = new DateTime(Lb[i]);
}
}
[Benchmark]
public bool[] LongMethod()
{
bool[] result = new bool[La.Length];
for(int i = 0; i < La.Length; i++)
{
result[i] = La[i] < Lb[i];
}
return result;
}
[Benchmark]
public bool[] DateTimeMethod()
{
bool[] result = new bool[Da.Length];
for (int i = 0; i < Da.Length; i++)
{
result[i] = Da[i] < Db[i];
}
return result;
}
}
结果:
| Method | N | Mean | Error | StdDev |
|--------------- |----------- |---------:|----------:|----------:|
| LongMethod | 1000000 | 1.460 ms | 0.0253 ms | 0.0370 ms |
| DateTimeMethod | 1000000 | 1.467 ms | 0.0292 ms | 0.0380 ms |
所以切换到长:
此外,推荐阅读 Erik Lippert 关于性能的博客