由于Ian Kent的评论,我在https://gitter.im/dotnet/corefx上提问,他们知道了答案。令人尴尬的简单:
var i = 1;
Span<char> span = new char[100];
var ok = i.TryFormat(span,out var charsWritten);
由于好几天没找到答案了,我想继续我的代码,所以我写了自己的方法,但是使用char []而不是Span。我用BenchmarkRunner测量了不同方法写入具有7'000'000 int的50 MB CSV文件的速度:
60毫秒:写入相同的常量字符串。这提供了一个基线,DotNet仅需要写入文件多长时间
for(int i = 0; i
610毫秒:使用ToString()
for(int i = 0; i
308毫秒:使用TryFormat(Span)
185毫秒:使用我自己的方法和char []
令人惊讶的是,字符串对话所花的时间比编写实际文件所花的时间长10倍。我本来希望硬盘比任何软件都要慢得多。
我们被告知Span将解决许多性能问题。不多。如果他们使用char []似乎会更好。
跨度测试代码
public void WriteTo4() {
var PathFileName = directoryInfo.FullName + @"\Test1.csv";
using (var fileStream = new FileStream(PathFileName,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None,bufferSize,FileOptions.SequentialScan)) {
using (var streamWriter = new StreamWriter(fileStream)) {
var lineBuffer = new char[100];
Span<char> span = lineBuffer;
for (int i = 0; i < iterations; i++) {
var ok = i.TryFormat(span,out var charsWritten);
lineBuffer[charsWritten++] = ';';
var span1 = span[charsWritten..];
ok = (i+1).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
span1 = span1[charsWritten..];
ok = (i+2).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
span1 = span1[charsWritten..];
ok = (i+3).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
span1 = span1[charsWritten..];
ok = (i+4).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
span1 = span1[charsWritten..];
ok = (i+5).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
span1 = span1[charsWritten..];
ok = (i+6).TryFormat(span1,out charsWritten);
span1[charsWritten++] = ';';
var ca = lineBuffer[..(lineBuffer.Length - span1.Length + charsWritten)];
streamWriter.WriteLine(lineBuffer,lineBuffer.Length - span1.Length + charsWritten);
}
}
}
}
使用char []
测试代码
public void WriteTo3() {
var PathFileName = directoryInfo.FullName + @"\Test1.csv";
using (var fileStream = new FileStream(PathFileName,FileOptions.SequentialScan)) {
using (var streamWriter = new StreamWriter(fileStream)) {
var lineBuffer = new char[100];
for (int i = 0; i < iterations; i++) {
var index = 0;
lineBuffer.Write3(i,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+1,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+2,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+3,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+4,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+5,ref index);
lineBuffer[index++] = ';';
lineBuffer.Write3(i+6,ref index);
lineBuffer[index++] = ';';
streamWriter.WriteLine(lineBuffer,index);
}
}
}
}
public static void Write3(this char[] charArray,int i,ref int index) {
if (i<0) {
charArray[index++] = '-';
i = -i;
}
int start = index;
while (i>9) {
charArray[index++] = (char)((i % 10) + '0');
i /= 10;
}
charArray[index++] = (char)(i + '0');
var end = index-1;
while (end>start) {
var temp = charArray[end];
charArray[end--] = charArray[start];
charArray[start++] = temp;
}
}
,
您如何尝试通过将所有数字传递来将int
直接解析为char
数组,将其转换为char
-s并将它们直接存储到目的地。
public static ReadOnlySpan<char> ToSpan(int src)
{
int len = GetLength(src);
Span<char> chars = new char[len];
for (int i = 0; i < chars.Length; i++)
{
chars[i]= (char)((Math.Floor(src / Math.Pow(10,(chars.Length - i - 1))) % 10) + 48);
}
return chars;
static int GetLength(int src)
{
int len = 0;
while (src > 0)
{
src = src / 10;
len++;
}
return len;
}
}
static void Main(string[] args)
{
int original = 3334;
var data = ToSpan(original);
var copy= int.Parse(data);
Console.WriteLine(copy);
}
PS
- 糟糕的是,您需要首先在
int
上进行迭代才能获得目的地的长度。
- 您肯定可以对我从数字转换为字符的方式进行一些优化,也许还可以对数字进行分隔的方式进行优化。
本文链接:https://www.f2er.com/3147388.html