如何在C#中将int转换为char []而不产生垃圾

Ste*_*son 5 .net c#

毫无疑问,鉴于ToString()and 的可用性,这似乎是一个奇怪的请求,Convert.ToString()但是我需要将无符号整数(即UInt32)转换为其字符串表示形式,但是我需要将答案存储到中char[]

原因是我正在使用字符数组以提高效率,并且在将目标char[]初始化为对象创建时char[10](持有的字符串表示形式UInt32.MaxValue)的成员时,理论上应该可以进行转换而不会产生任何垃圾(通过我的意思是在托管堆中不生成任何临时对象。)

谁能看到实现这一目标的巧妙方法?

(如果有任何相关意义,我正在使用Framework 3.5SP1。)

arx*_*arx 5

进一步我上面的评论,我想知道 log10 是不是太慢了,所以我写了一个不使用它的版本。

对于四位数字,此版本的速度提高了约 35%,对于十位数字则降低了约 16%。

一个缺点是它需要缓冲区中完整的十位数字的空间。

我不发誓它没有任何错误!

public static int ToCharArray2(uint value, char[] buffer, int bufferIndex)
{
    const int maxLength = 10;

    if (value == 0)
    {
        buffer[bufferIndex] = '0';
        return 1;
    }

    int startIndex = bufferIndex + maxLength - 1;
    int index = startIndex;
    do
    {
        buffer[index] = (char)('0' + value % 10);
        value /= 10;
        --index;
    }
    while (value != 0);

    int length = startIndex - index;

    if (bufferIndex != index + 1)
    {
        while (index != startIndex)
        {
            ++index;
            buffer[bufferIndex] = buffer[index];
            ++bufferIndex;
        }
    }

    return length;
}
Run Code Online (Sandbox Code Playgroud)

更新

我应该补充一点,我使用的是 Pentium 4。更新的处理器可以更快地计算超越函数。

结论

我昨天意识到我犯了一个小学生错误并在调试版本上运行了基准测试。所以我再次运行它们,但实际上并没有太大区别。第一列显示正在转换的数字中的位数。其余列显示转换 500,000 个数字的时间(以毫秒为单位)。

uint 的结果:

    luc1   arx henk1  luc3 henk2  luc2
 1   715   217   966   242   837   244
 2   877   420  1056   541   996   447
 3  1059   608  1169   835  1040   610
 4  1184   795  1282  1116  1162   801
 5  1403   969  1405  1396  1279   978
 6  1572  1149  1519  1674  1399  1170
 7  1740  1335  1648  1952  1518  1352
 8  1922  1675  1868  2233  1750  1545
 9  2087  1791  2005  2511  1893  1720
10  2263  2103  2139  2797  2012  1985
Run Code Online (Sandbox Code Playgroud)

ulong 的结果:

    luc1   arx henk1  luc3 henk2  luc2
 1   802   280   998   390   856   317
 2   912   516  1102   729   954   574
 3  1066   746  1243  1060  1056   818
 4  1300  1141  1362  1425  1170  1210
 5  1557  1363  1503  1742  1306  1436
 6  1801  1603  1612  2233  1413  1672
 7  2269  1814  1723  2526  1530  1861
 8  2208  2142  1920  2886  1634  2149
 9  2360  2376  2063  3211  1775  2339
10  2615  2622  2213  3639  2011  2697
11  3048  2996  2513  4199  2244  3011
12  3413  3607  2507  4853  2326  3666
13  3848  3988  2663  5618  2478  4005
14  4298  4525  2748  6302  2558  4637
15  4813  5008  2974  7005  2712  5065
16  5161  5654  3350  7986  2994  5864
17  5997  6155  3241  8329  2999  5968
18  6490  6280  3296  8847  3127  6372
19  6440  6720  3557  9514  3386  6788
20  7045  6616  3790 10135  3703  7268
Run Code Online (Sandbox Code Playgroud)

luc1:Lucero 的第一个函数

arx:我的功能

henk1:亨克的函数

luc3 Lucero 的第三个函数

henk2:Henk 的函数,没有复制到 char 数组;即只是测试 ToString() 的性能。

luc2:Lucero 的第二个函数

特殊的顺序是它们被创建的顺序。

我还在没有 henk1 和 henk2 的情况下运行了测试,因此不会有垃圾收集。其他三个功能的时间几乎相同。一旦基准超过三位数,内存使用就稳定了:因此 GC 发生在 Henk 的函数期间,并且不会对其他函数产生不利影响。

结论:只需调用 ToString()