Csv解析性能优化

This commit is contained in:
2024-02-08 22:19:59 +08:00
parent 8db7c71170
commit 41a1dc8a4f
4 changed files with 133 additions and 10 deletions

View File

@@ -49,43 +49,44 @@ public class CsvReader : IDataReader
if (string.IsNullOrWhiteSpace(str))
return false;
var fields = ParseRow(str, QuoteChar, Delimiter);
var fields = ParseRow(str, QuoteChar, Delimiter[0]);
Current = new DataRecord(fields, TableName, Headers);
return true;
}
public string[] ParseRow(ReadOnlySpan<char> source, char quoteChar, string delimiter)
public static string[] ParseRow(ReadOnlySpan<char> source, char quoteChar, char delimiter)
{
var result = new List<string>();
var index = -1;
var current = new StringBuilder();
var current = new StringBuilder(source.Length);
var hasQuote = false;
var hasSlash = false;
while (index < source.Length - 1)
{
index++;
if (hasSlash == false && source[index] == '\\')
var currChar = source[index];
if (hasSlash == false && currChar == '\\')
{
hasSlash = true;
current.Append('\\');
continue;
}
if (hasSlash == false && source[index] == quoteChar)
if (hasSlash == false && currChar == quoteChar)
{
hasQuote = !hasQuote;
current.Append(source[index]);
current.Append(currChar);
continue;
}
if (hasQuote == false && source[index] == delimiter[0])
if (hasQuote == false && currChar == delimiter)
{
result.Add(current.ToString());
current.Clear();
}
else
{
current.Append(source[index]);
current.Append(currChar);
}
hasSlash = false;
@@ -94,6 +95,54 @@ public class CsvReader : IDataReader
result.Add(current.ToString());
return result.ToArray();
}
public static List<string> ParseRowFaster(ReadOnlySpan<char> source, char quoteChar, char delimiter, int columnCount = 10)
{
var result = new List<string>(columnCount);
var index = -1;
var hasQuote = false;
var hasSlash = false;
var start = 0;
var end = 0;
var len = source.Length - 1;
while (index < len)
{
++index;
var currChar = source[index];
if (!hasSlash)
{
if (currChar is '\\')
{
hasSlash = true;
++end;
continue;
}
if (currChar == quoteChar)
{
hasQuote = !hasQuote;
++end;
continue;
}
}
if (!hasQuote && currChar == delimiter)
{
result.Add(source[start..(end + 1)].ToString());
start = end + 2;
}
else
{
++end;
}
hasSlash = false;
}
result.Add(source[start..(end + 1)].ToString());
return result;
}
public virtual void Dispose()
{

View File

@@ -31,7 +31,7 @@ public class ZstReader : CsvReader
if (string.IsNullOrWhiteSpace(str))
return false;
var fields = ParseRow(str, QuoteChar, Delimiter);
var fields = ParseRow(str, QuoteChar, Delimiter[0]);
Current = new DataRecord(fields, TableName, Headers);
return true;
}