这些值是逗号分隔的,所以我使用stringbuilder来构建值。然后将它们写入适当的缓冲区。我注意到在builder.ToString和Parse函数中花了相当多的时间。我是否必须编写不安全的代码来克服这个问题?什么是实现我想要的最佳方式
private static void ReadSecondBySecondFileToEndBytes(FileInfo file, SafeDictionary<short, SafeDictionary<string, SafeDictionary<int, decimal>>> dayData)
{
string name = file.Name.Split('.')[0];
int result = 0;
int index = result;
int length = 1*1024; //1 kb
char[] buffer = new char[length];
StringBuilder builder = new StringBuilder();
bool pendingTick = true;
bool pendingSymbol = true;
bool pendingValue = false;
string characterString = string.Empty;
short symbol = 0;
int tick = 0;
decimal value;
using (StreamReader streamReader = (new StreamReader(file.FullName)))
{
while ((result = streamReader.Read(buffer, 0, length)) > 0)
{
int i = 0;
while (i < result)
{
if (buffer[i] == '\r' || buffer[i] == '\n')
{
pendingTick = true;
if (pendingValue)
{
value = decimal.Parse(builder.ToString());
pendingSymbol = true;
pendingValue = false;
dayData[symbol][name][tick] = value;
builder.Clear();
}
}
else if (buffer[i] == ',') // new value to capture
{
if (pendingTick)
{
tick = int.Parse(builder.ToString());
pendingTick = false;
}
else if (pendingSymbol)
{
symbol = short.Parse(builder.ToString());
pendingValue = true;
pendingSymbol = false;
}
else if (pendingValue)
{
value = decimal.Parse(builder.ToString());
pendingSymbol = true;
pendingValue = false;
dayData[symbol][name][tick] = value;
}
builder.Clear();
}
else
builder.Append(buffer[i]);
i++;
}
}
}
}
答案 0 :(得分:2)
我的建议是不要像现在一样尝试解析大部分文件,但是请选择以下内容:
using (var reader = File.OpenText("<< filename >>"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] parts = line.Split(',');
// Process the different parts of the line here.
}
}
这里的主要区别是你没有解析行结尾和逗号分隔。优点是,当您使用ReadLine()
等高级方法时,StreamReader
(File.OpenText()
返回)可以优化逐行读取文件。 String.Split()
也是如此。
使用这些高级方法几乎总是比你自己解析缓冲区更快。
使用上述方法,您不必再使用StringBuilder
了,只需获取您的值:
tick = int.Parse(parts[0]);
symbol = short.Parse(parts[1]);
value = decimal.Parse(parts[2]);
dayData[symbol][name][tick] = value;
我还没有验证上面的代码段;请验证这些行是否正确,或根据您的业务逻辑更正这些行。
答案 1 :(得分:1)
你得到了错误的印象。是的,在测试程序时,您确实会在Parse()和构建器中看到大部分时间。因为这是唯一可以完成任何实际工作的代码。
但是在制作中不会这样。然后所有时间都将花在StreamReader上。因为文件不会出现在文件系统缓存中,就像在开发机器上反复运行程序时一样。在生产中,必须从磁盘驱动器读取文件。而且速度非常慢,磁盘I / O是您程序的真正瓶颈。使解析速度提高两倍只会使程序的速度提高几个百分点(如果有的话)。
不要为了这么小的收益而损害代码的可靠性或可维护性。