我正在创建一个月的日期列表。我想知道什么会更有效率
List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(1).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
或
List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr=StartDay; !curr.Equals(NextMonth); curr=curr.AddDays(1)) {
dates.Add(curr);
}
return dates;
}
基本上,新的DateTime()或DateTime.addDays更有效率。
更新:
static void Main(string[] args) {
System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
long t1, t2, total;
List<DateTime> l;
DateTime begin = DateTime.Now;
total = 0L;
for (int i=0; i<10; i++) {
sw.Start();
l = GetDates(begin);
sw.Stop();
sw.Stop();
t1 = sw.ElapsedTicks;
sw.Reset();
sw.Start();
l = GetDates2(begin);
sw.Stop();
t2=sw.ElapsedTicks;
total += t1- t2;
Console.WriteLine("Test {0} : {1} {2} : {3}", i,t1,t2, t1- t2);
}
Console.WriteLine("Total: {0}", total);
Console.WriteLine("\n\nDone");
Console.ReadLine();
}
static List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(10000).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
static List<DateTime> GetDates2(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(10000);
for (DateTime curr=StartDay; !curr.Equals(NextMonth); curr=curr.AddDays(1)) {
dates.Add(curr);
}
return dates;
}
Test 0 : 2203229 63086205 : -60882976 Test 1 : 63126483 102969090 : -39842607 Test 2 : 102991588 93487982 : 9503606 Test 3 : 93510942 69439034 : 24071908 Test 4 : 69465137 70660555 : -1195418 Test 5 : 70695702 68224849 : 2470853 Test 6 : 68248593 63555492 : 4693101 Test 7 : 63578536 65086357 : -1507821 Test 8 : 65108190 64035573 : 1072617 Test 9 : 64066128 64933449 : -867321 Total: -62484058 Done
结果一直是负面的...方式为负,所以,看起来像构造函数和整数测试是更有效的方法。
答案 0 :(得分:5)
测量它 - 编写测试程序,看看哪一个花费的时间更短。
答案 1 :(得分:3)
我相信datetime操作会返回新的日期时间结构,因此您将以任何方式创建新实例。
http://msdn.microsoft.com/en-us/library/system.datetime.aspx
答案 2 :(得分:3)
除非你正在进行一些财务处理,否则我会更担心可读性而不是性能。如果这是一个经过证实的瓶颈,那就开始担心像这里的表现了。
答案 3 :(得分:2)
因为他们最终都做了同样的事情,所以差别不大。
如果您正在寻找效率,请使用滴答声。在完成任何数学运算之前,DateTime中的所有(我已经看到)调用最终会被转换为刻度。
答案 4 :(得分:1)
很难想象这会产生显着差异的情况,但Reflector表明AddDays
技术应该更有效率。
比较AddDays
(来自Add(Double, Int32)
)
long num = (long) ((value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
if ((num <= -315537897600000L) || (num >= 0x11efae44cb400L)) {
// Throw omitted
}
return this.AddTicks(num * 0x2710L);
DateTime(int, int, int)
构造函数的核心逻辑(来自DateToTicks
):
if (((year >= 1) && (year <= 0x270f)) && ((month >= 1) && (month <= 12)))
{
int[] numArray = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
if ((day >= 1) && (day <= (numArray[month] - numArray[month - 1])))
{
int num = year - 1;
int num2 = ((((((num * 0x16d) + (num / 4)) - (num / 100)) + (num / 400)) + numArray[month - 1]) + day) - 1;
return (num2 * 0xc92a69c000L);
}
}
// Throw omitted
AddDays
只需将指定的天数转换为等效的刻度数(一个长整数),然后将其添加到现有刻度中。
使用年/月/日构造函数创建新的DateTime
需要更多计算。该构造函数必须检查指定年份是否为闰年,每月分配一个天数,执行一系列额外操作,最后得到这三个数字代表的滴答数。
编辑:DateTime.AddDays(int)
比new DateTime(int, int, int)
快,但您的第一个算法比第二个算法快。这可能是因为第二算法中的迭代成本要高得多。正如您在编辑中观察到的那样,这可能是因为DateTime.Equals
比比较整数更昂贵。
答案 5 :(得分:1)
这是一个有效的测试程序,实施的算法可以实际比较它们(但它们仍然需要工作):
class Program
{
static void Main(string[] args)
{
IList<DateTime> l1, l2;
DateTime begin = new DateTime(2000, 1, 1);
Stopwatch timer1 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l1 = GetDates(begin);
timer1.Stop();
Stopwatch timer2 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l2 = GetDates2(begin);
timer2.Stop();
Console.WriteLine("new DateTime: {0}\n.AddDays: {1}",
timer1.ElapsedTicks, timer2.ElapsedTicks);
Console.ReadLine();
}
static IList<DateTime> GetDates(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
int TotalDays = DateTime.DaysInMonth(StartDay.Year, StartDay.Month);
for (int i = 0; i < TotalDays; i++)
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i + 1));
return dates;
}
static IList<DateTime> GetDates2(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr = StartDay; !curr.Equals(NextMonth); curr = curr.AddDays(1))
dates.Add(curr);
return dates;
}
} // class
输出(我添加了逗号):
new DateTime: 545,307,375 .AddDays: 180,071,512
这些结果对我来说非常清楚,但老实说,我认为他们会更接近。
答案 6 :(得分:0)
我同意马克。自己测试两种方法,看看哪一种方法更快。使用秒表类可以准确计算每个方法运行的时间。我的第一个猜测是,既然最终都会创建新的结构,那么任何速度差异都可以忽略不计。此外,只生成一个月的日期(最多31天),我认为任何一种方法都不会比另一种方法慢得多。也许你是在产生数千或数百万个日期,它会有所作为,但是对于31个日期,它可能是过早的优化。