我的情况概述:
我的任务是从文件中读取字符串,并将它们重新格式化为更有用的格式。重新格式化输入后,我必须将其写入输出文件。
这是必须完成的示例。 文件行示例:
ANO=2010;CPF=17834368168;YEARS=2010;2009;2008;2007;2006 <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2010</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><RESTITUICAO><CPF>17834368168</CPF><ANO>2009</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><RESTITUICAO><CPF>17834368168</CPF><ANO>2008</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><RESTITUICAO><CPF>17834368168</CPF><ANO>2007</ANO><SITUACAODECLARACAO>Sua declaração consta como Pedido de Regularização(PR), na base de dados da Secretaria da Receita Federal do Brasil</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><RESTITUICAO><CPF>17834368168</CPF><ANO>2006</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
此输入文件的每一行都有两个重要信息:CPF
,这是我将使用的文档编号,以及 XML
文件(代表查询的返回用于数据库中的文档)。
我必须达到的目标:
此旧格式
中的每个文档都有一个XML
,其中包含所有年份(2006 年至2010 年)的查询返回值。重新格式化后,每条输入线转换为 5 条输出线:
CPF=17834368168;YEARS=2010; <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2010</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
CPF=17834368168;YEARS=2009; <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2009</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
CPF=17834368168;YEARS=2008; <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2008</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
CPF=17834368168;YEARS=2007; <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2007</ANO><SITUACAODECLARACAO>Sua declaração consta como Pedido de Regularização(PR), na base de dados da Secretaria da Receita Federal do Brasil</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
CPF=17834368168;YEARS=2006; <?xml version='1.0' encoding='ISO-8859-1'?><QUERY><RESTITUICAO><CPF>17834368168</CPF><ANO>2006</ANO><SITUACAODECLARACAO>Sua declaração não consta na base de dados da Receita Federal</SITUACAODECLARACAO><DATACONSULTA>05/01/2012</DATACONSULTA></RESTITUICAO><STATUS><RESULT>TRUE</RESULT><MESSAGE></MESSAGE></STATUS></QUERY>
一行,包含有关该文档的每年信息。所以基本上,输出文件的长度是输入文件的 5 倍。
性能问题:
每个文件有 400,000 行,我有 133 个文件要处理。
目前,这是我的应用程序的流程:
- 打开一个文件
- 读一行
- 将其解析为新格式
- 将行写入输出文件
- 转到 2 直到没有左边的行
- Goto1 直到没有剩下的文件
每个输入文件大约 700MB,读取文件并将转换后的版本写入另一个文件需要很长时间。一个 400KB 的文件需要大约 30 秒才能完成该过程。
额外信息:
我的机器运行在 Intel i5 处理器上,内存为 8GB。
我没有实例化大量对象来避免内存。泄漏,我在输入文件打开时使用 using
子句。
我该怎么做才能让它运行得更快?
最佳答案
我不知道您的代码是什么样的,但这是我的盒子上的一个示例(诚然带有 SSD 和 i7,但是......)在大约 50 毫秒内处理一个 400K 的文件。
我什至没有考虑过优化它 - 我已经用我能做到的最简洁的方式编写了它。 (请注意,它都是延迟计算的;File.ReadLines
和 File.WriteAllLines
负责打开和关闭文件。)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
class Test
{
public static void Main()
{
Stopwatch stopwatch = Stopwatch.StartNew();
var lines = from line in File.ReadLines("input.txt")
let cpf = ParseCpf(line)
let xml = ParseXml(line)
from year in ParseYears(line)
select cpf + year + xml;
File.WriteAllLines("output.txt", lines);
stopwatch.Stop();
Console.WriteLine("Completed in {0}ms", stopwatch.ElapsedMilliseconds);
}
// Returns the CPF, in the form "CPF=xxxxxx;"
static string ParseCpf(string line)
{
int start = line.IndexOf("CPF=");
int end = line.IndexOf(";", start);
// TODO: Validation
return line.Substring(start, end + 1 - start);
}
// Returns a sequence of year values, in the form "YEAR=2010;"
static IEnumerable<string> ParseYears(string line)
{
// First year.
int start = line.IndexOf("YEARS=") + 6;
int end = line.IndexOf(" ", start);
// TODO: Validation
string years = line.Substring(start, end - start);
foreach (string year in years.Split(';'))
{
yield return "YEARS=" + year + ";";
}
}
// Returns all the XML from the leading space onwards
static string ParseXml(string line)
{
int start = line.IndexOf(" <?xml");
// TODO: Validation
return line.Substring(start);
}
}
关于c# - 写入文件 C# 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9437265/