gpt4 book ai didi

c# - 将数组拆分为大小受限的 CSV 字符串

转载 作者:行者123 更新时间:2023-11-30 22:31:15 25 4
gpt4 key购买 nike

我正在寻找一种将大型 int[] 转换为 csv 字符串的 string[] 的有效方法,其中每个 csv 限制为最多 4000 个字符。数组中的值可以是 1 到 int.MaxValue 之间的任何值。

这是我的最终代码:

public static string[] GetCSVsFromArray(int[] array, int csvLimit)
{
List<string> parts = new List<string>();
StringBuilder sb = new StringBuilder();
foreach(int id in array)
{
string intId = id.ToString();
if (sb.Length + intId.Length < csvLimit)
sb.Append(intId).Append(",");
else
{
if (sb.Length > 0)
sb.Length--;
parts.Add(sb.ToString());
sb.Length = 0;
}
}
if(sb.Length>0)
parts.Add(sb.ToString());
return parts.ToArray();
}

有没有更有效的方法来做到这一点?

所以这就是我现在使用的(我能够将返回参数更改为 List 类型以在最后保存 ToArray() 调用):

public static List<string> GetCSVsFromArray(int[] array, int csvLimit)
{
List<string> parts = new List<string>();
StringBuilder sb = new StringBuilder();
foreach(int id in array)
{
string intId = id.ToString();
if (sb.Length + intId.Length < csvLimit)
sb.Append(intId).Append(",");
else
{
if (sb.Length > 0)
sb.Length--;
parts.Add(sb.ToString());
sb.Length = 0;
}
}
if(sb.Length>0)
parts.Add(sb.ToString());
return parts;
}

性能结果:

10,000,000 个项目 csv 限制为 4000 个字符

  • 原始:2,887.488 毫秒
  • GetIntegerDigitCount:3105.355ms
  • 最终:2883.587 毫秒

虽然在我的开发人员机器上删除 ToArray() 调用只节省了 4 毫秒,但这似乎在速度慢得多的机器上产生了显着差异(在 DELL D620 上节省了 200 多毫秒)

最佳答案

为每个数字创建新字符串只是为了计算数字位数时,您会进行大量堆内存分配。使用 following method计算数字中的位数(参见下面的方法)。

所以代替

string intId = id.ToString();
if (sb.Length + intId.Length < csvLimit)

只需使用:

if (sb.Length + this.GetIntegerDigitCount(id) < csvLimit)

结果:

  • 处理 1000 万个数字时快 2 倍
  • 旧:4316 毫秒,新:1983 毫秒,差异:2333 毫秒。更快 217.6%

编辑:更多关于大 csv 限制的结果

Items:10000000; csvLimit:4000; Old:2091ms, New:1868ms, Diff:223ms faster = 111.937901498929%


我用来测量时间的代码:

 double elapsedOld = 0;
double elapsedNew = 0;
int count = 10000000;
int csvLimit = 4000;
var items = Enumerable.Range(0, count).ToArray();
var watch = Stopwatch.StartNew();
this.GetCsVsFromArray(items, csvLimit);
watch.Stop();
elapsedOld = watch.ElapsedMilliseconds;

watch = Stopwatch.StartNew();
this.GetCsVsFromArrayTuned(items, csvLimit);
watch.Stop();
elapsedNew = watch.ElapsedMilliseconds;
var stat = String.Format(
"Items:{0}; csvLimit:{1}; Old:{2}ms, New:{3}ms, Diff:{4}ms faster = {5}%",
count,
csvLimit,
elapsedOld,
elapsedNew,
elapsedOld - elapsedNew,
elapsedOld * 100 / elapsedNew);

GetIntegerDigitCount:

public int GetIntegerDigitCount(int valueInt)
{
double value = valueInt;
int sign = 0;
if (value < 0)
{
value = -value;
sign = 1;
}

if (value <= 9)
{
return sign + 1;
}

if (value <= 99)
{
return sign + 2;
}

if (value <= 999)
{
return sign + 3;
}

if (value <= 9999)
{
return sign + 4;
}

if (value <= 99999)
{
return sign + 5;
}

if (value <= 999999)
{
return sign + 6;
}

if (value <= 9999999)
{
return sign + 7;
}

if (value <= 99999999)
{
return sign + 8;
}

if (value <= 999999999)
{
return sign + 9;
}

return sign + 10;
}

关于c# - 将数组拆分为大小受限的 CSV 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9328061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com