Wpf &引用;“年度工作周”;算法需要改进
我有一个算法,可以扫描从.csv文件(大约3700行)读取的数据,并通过在该年的每个星期日运行count++来评估每个条目在一年中的哪个交易周,当日期在该周内时,将计数值指定为交易周 它正在工作,但性能落后。这是使用Task.Factory.StartNew运行的第三个函数(我也尝试过parallel.Invoke) 定时测试的结果 00:00:05.58之前 在:00:00:23.27之后 更新 在设定每个交易周后增加休息时间。时间有所改善,但仍然缓慢 新时间:00:00:15.74 就我们而言,一年中的第一周是第1周(不是0周),定义为从一年中的第一天到周日。如果一年中的第一天是星期天,则第1周的长度为1天Wpf &引用;“年度工作周”;算法需要改进,wpf,algorithm,c#-4.0,Wpf,Algorithm,C# 4.0,我有一个算法,可以扫描从.csv文件(大约3700行)读取的数据,并通过在该年的每个星期日运行count++来评估每个条目在一年中的哪个交易周,当日期在该周内时,将计数值指定为交易周 它正在工作,但性能落后。这是使用Task.Factory.StartNew运行的第三个函数(我也尝试过parallel.Invoke) 定时测试的结果 00:00:05.58之前 在:00:00:23.27之后 更新 在设定每个交易周后增加休息时间。时间有所改善,但仍然缓慢 新时间:00:00:15.74 就我们而
private void SetDefiniteWeeks()
{
string FileLoc = FilePath + Market + ".csv";
string[] Data = File.ReadAllLines(FileLoc);
var FileData = from D in Data
let DataSplit = D.Split(',')
select new
{
Date = DateTime.Parse(DataSplit[0]),
ClosingPrice = double.Parse(DataSplit[4])
};
//assign each date to it's relevant week
TradingWeek TW;
List<TradingWeek> tradingWeek = new List<TradingWeek>();
foreach (var pe in FileData)
{
// DateTime dt = pe.Date;
int Year = pe.Date.Year;
string End_of_Week = "Sunday";
int WeekCount = 0;
DateTime LoopDate_Begin = new DateTime(Year,1,1);
DateTime LoopDate_End = new DateTime(Year,12,31);
do
{
if (LoopDate_Begin.DayOfWeek.ToString() == End_of_Week)
{
WeekCount++;
if (LoopDate_Begin.DayOfYear > pe.Date.DayOfYear && LoopDate_Begin.DayOfYear < (pe.Date.DayOfYear + 7))
{
TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
break;
}
}
LoopDate_Begin = LoopDate_Begin.AddDays(1);
} while (LoopDate_Begin.Date.ToString() != LoopDate_End.Date.ToString());
}
}
如果我没记错的话,你不需要在加入TradingWeek后再看下去 所以,你可以
break;
之后
tradingWeek.Add(TW);
然后你甚至可以省略
&& LoopDate_Begin.DayOfYear < (pe.Date.DayOfYear + 7)
和&LoopDate\u Begin.DayOfYear<(pe.Date.DayOfYear+7)
条件,因为第一部分只有一次为真:对于您想要的间隔。三个快速想法:
- 为什么你每次只增加一天,看看是不是星期天。当然,一旦你找到了你的第一个星期天,你可以再加上七天来找到下一个星期天
- 如果您在开始之前按日期时间订购您的pes,那么您不需要在年初为每一个pes重新启动,您可以从您停止的地方开始
- 正如尼古拉斯所说,在增加交易周后休息。在你已经知道答案之后,就不需要经历今年剩下的时间了
TradingWeek TW;
List tradingWeek=新列表();
字符串结束\u Week=“Sunday”;
var orderedData=FileData.OrderBy(x=>x.Date)
DateTime LoopDate_Begin=新的日期时间(orderedData[0]。日期。年份,1,1);
int WeekCount=1;
while(LoopDate\u Begin.DayOfWeek.ToString()!=周末)
{
LoopDate\u Begin=LoopDate\u Begin.AddDays(1);
}
foreach(orderedData中的变量pe)
{
做
{
if(LoopDate\u Begin.dayof year>pe.Date.dayof year&&LoopDate\u Begin.dayof year<(pe.Date.dayof year+7))
{
TW=新交易周{Week=WeekCount,Date=pe.Date};
交易周。增加(TW);
打破
}
WeekCount++;
LoopDate\u Begin=LoopDate\u Begin.AddDays(7);
}虽然(正确);//这里需要小心
}
您甚至可以采用无环方法,将开始一周的天数除以7,然后进行一些清理工作;) 通过直接计算周数,你能完全摆脱你的do
循环吗?类似于公认的答案。你根本不需要数数,只需快速计算即可。这假设年初的部分周为第1周,第2周从第一个星期一开始
List<TradingWeek> tradingWeek = new List<TradingWeek>();
foreach (var pe in FileData)
{
var date = pe.Date;
while (date.DayOfWeek != DayOfWeek.Sunday)
date = date.AddDays(1);
var week = date.DayOfYear/7+1;
var TW = new TradingWeek {Week = week, Date = pe.Date};
tradingWeek.Add(TW);
}
List tradingWeek=新列表();
foreach(FileData中的var-pe)
{
var日期=pe.日期;
while(date.DayOfWeek!=DayOfWeek.Sunday)
日期=日期。添加天数(1);
var week=日期。DayOfYear/7+1;
var TW=新交易周{Week=Week,Date=pe.Date};
交易周。增加(TW);
}
我不确定这是否是你想要的,但在阅读了评论后,我觉得这可能会奏效(?)
编辑:更改为CalendarWeekRule.FirstDay,因为它是OP想要的(更多?)。在@nicolas78的回复之后,类似的内容应该会起作用
int Year = pe.Date.Year;
DateTime Year_Begin = new DateTime(Year,1,1);
int Jan1DayOfWeek = Year_Begin.DayOfWeek;
foreach (var pe in FileData)
{
int WeekCount = (pe.Date.DayOfYear - Jan1DayOfWeek) % 7 + 1;
TradingWeek TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
}
根据DayOfWeek和DayOfYear的计数方式(即0或1),以及mod操作的工作方式,您可能需要稍微调整WeekCount计算。有一个内置功能,可以根据.NET中的日期获取一年中的一周。下面显示了一个示例,但可能需要进行一些调整以适应您的业务场景:
System.Globalization.CultureInfo myCI = new System.Globalization.CultureInfo("en-US");
int week = myCI.Calendar.GetWeekOfYear(DateTime.Now.ToUniversalTime(), System.Globalization.CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Sunday);
感谢Martin,orderedData[0]。Date.Year给了我一个错误:错误2无法将带[]的索引应用于“System.Linq.IORDerenumerable”类型的表达式,请改为尝试orderedDate.First().Date.Year。这是一件小事,但当您最终将它与DayOfWeek枚举进行比较时,为什么要将“周末的结束”存储在字符串中?最好是周末结束=周末周日。。。LoopDate\u Begin.DayOfWeek!=如果这是一个选项,您可以使用内置函数:CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(someDate,CalendarWeekRule.FirstFourDayWeek,DayOfWeek.Sunday)非常好。Jesper我不确定这是否会产生正确的结果,因为CalendarWeekRule。请查看我的更新。@克里斯:如果您使用CalendarWeekRule.FirstDay怎么办?谢谢Jesper,检查了过去几年的第一天,值都是正确的!我同意;而且无法理解“优化”循环方法的解决方案是如何被提升的。泽勒对胜利的祝贺!
var calendar = CultureInfo.CurrentCulture.Calendar;
var tradingWeek = (from pe in FileData
select new TradingWeek
{
Date = pe.Date,
Week = calendar.GetWeekOfYear(pe.Date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
}).ToList();
int Year = pe.Date.Year;
DateTime Year_Begin = new DateTime(Year,1,1);
int Jan1DayOfWeek = Year_Begin.DayOfWeek;
foreach (var pe in FileData)
{
int WeekCount = (pe.Date.DayOfYear - Jan1DayOfWeek) % 7 + 1;
TradingWeek TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
}
System.Globalization.CultureInfo myCI = new System.Globalization.CultureInfo("en-US");
int week = myCI.Calendar.GetWeekOfYear(DateTime.Now.ToUniversalTime(), System.Globalization.CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Sunday);