.NET字符串的最大可能长度是多少?

时间:2022-04-13 21:40:43

What is the longest string that can be created in .NET? The docs for the String class are silent on this question as far as I can see, so an authoritative answer might require some knowledge of internals. Would the maximum change on a 64-bit system?

在。net中可以创建的最长的字符串是什么?就我所知,String类的文档在这个问题上保持沉默,所以权威的答案可能需要一些内部的知识。64位系统的最大变化是什么?

[This is asked more for curiosity than for practical use - I don't intend to create any code that uses gigantic strings!]

这是出于好奇而不是实际用途,我不打算创建任何使用巨大字符串的代码!

7 个解决方案

#1


284  

The theoretical limit may be 2,147,483,647, but the practical limit is nowhere near that. Since no single object in a .NET program may be over 2 GB and the string type uses unicode (two bytes for each character), the best you could do is 1,073,741,823, but you're not likely to ever be able to allocate that on a 32-bit machine.

理论上的极限可能是2,147,483,647,但实际的极限远没有那么大。由于. net程序中没有一个对象可能超过2gb,而且字符串类型使用unicode(每个字符有两个字节),所以最好的方法是1,073,741,823,但是您不太可能在32位机器上分配它。

This is one of those situations where ["If you have to ask, you're probably doing something wrong."] is the case.

这是其中一种情况,“如果你要问,你可能做错了。”]。

#2


65  

Based on my highly scientific and accurate experiment, it tops out on my machine well before 1,000,000,000 characters. (I'm still running the code below to get a better pinpoint).

基于我高度科学和准确的实验,它在我的机器上早在10亿字符之前就已经是最好的了。(我仍然在运行下面的代码以获得更好的定位)。

UPDATE: After a few hours, I've given up. Final results: Can go a lot bigger than 100,000,000 characters, instantly given System.OutOfMemoryException at 1,000,000,000 characters.

更新:几个小时后,我放弃了。最终结果:可以在给定的系统中运行超过1亿个字符。OutOfMemoryException在1000000000个字符。

using System;
using System.Collections.Generic;

public class MyClass
{
    public static void Main()
    {
        int i = 100000000;
        try
        {
            for (i = i; i <= int.MaxValue; i += 5000)
            {
                string value = new string('x', i);
                //WL(i);
            }
        }
        catch (Exception exc)
        {
            WL(i);
            WL(exc);
        }
        WL(i);
        RL();
    }

    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine(); 
    }

    private static void Break() 
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

#3


48  

Since the Length property of System.String is an Int32, I would guess that that the maximum length would be 2,147,483,647 chars (max Int32 size). If it allowed longer you couldn't check the Length since that would fail.

因为系统的长度性质。String是Int32,我猜最大长度是2147,483,647 chars (max Int32大小)。如果允许更长的时间,您就不能检查长度,因为那样会失败。

#4


23  

For anyone coming to this topic late, I could see that hitscan's "you probably shouldn't do that" might cause someone to ask what they should do…

如果有人来晚了,我可以看到hitscan的“你可能不应该这样做”可能会让别人问他们该怎么做……

The StringBuilder class is often an easy replacement. Consider one of the stream-based classes especially, if your data is coming from a file.

StringBuilder类通常是一个容易的替代品。如果数据来自一个文件,请特别考虑一个基于流的类。

The problem with s += "stuff" is that it has to allocate a completely new area to hold the data and then copy all of the old data to it plus the new stuff - EACH AND EVERY LOOP ITERATION. So, adding five bytes to 1,000,000 with s += "stuff" is extremely costly. If what you want is to just write five bytes to the end and proceed with your program, you have to pick a class that leaves some room for growth:

s += "stuff"的问题是,它必须分配一个全新的区域来保存数据,然后将所有旧数据和新数据(每次循环迭代)复制到它。因此,用s += "stuff"增加5个字节到1,000,000是非常昂贵的。如果你想要在最后写5个字节,然后继续你的程序,你必须选择一个有发展空间的类:

StringBuilder sb = new StringBuilder(5000);
for (; ; )
    {
        sb.Append("stuff");
    }

StringBuilder will auto-grow by doubling when it's limit is hit. So, you will see the growth pain once at start, once at 5,000 bytes, again at 10,000, again at 20,000. Appending strings will incur the pain every loop iteration.

当达到极限时,StringBuilder将自动增加一倍。你会看到增长的痛苦,开始的时候,5000字节,10000字节,20000字节。附加字符串将导致每次循环迭代的痛苦。

#5


6  

Strings aren't limited by integer as is commonly believed.

字符串不像通常认为的那样受到整数的限制。

Memory restrictions aside, Strings cannot have more than 230 (1,073,741,824) characters, since a 2GB limit is imposed by the Microsoft CLR (Common Language Runtime).

除了内存限制,字符串不能超过230(1073,741,824)字符,因为2GB的限制是由Microsoft CLR(公共语言运行时)施加的。

Hopefully, this may change in the future.

希望这能在未来改变。

#6


2  

200 megs... at which point your app grinds to a virtual halt, has about a gig working set memory, and the o/s starts to act like you'll need to reboot.

200 mb……这时,你的应用程序就会变成一个虚拟的停顿,有一个临时的工作设置内存,o/s开始表现得像你需要重新启动一样。

static void Main(string[] args)
{
    string s = "hello world";
    for(;;)
    {
        s = s + s.Substring(0, s.Length/10);
        Console.WriteLine(s.Length);
    }
}

12
13
14
15
16
17
18
...
158905664
174796230
192275853
211503438

#7


1  

Since String.Length is an integer (that is an alias for Int32), its size is limited to Int32.MaxValue unicode characters. ;-)

因为字符串。长度是一个整数(即Int32的别名),其大小被限制为Int32。MaxValue unicode字符。:-)

#1


284  

The theoretical limit may be 2,147,483,647, but the practical limit is nowhere near that. Since no single object in a .NET program may be over 2 GB and the string type uses unicode (two bytes for each character), the best you could do is 1,073,741,823, but you're not likely to ever be able to allocate that on a 32-bit machine.

理论上的极限可能是2,147,483,647,但实际的极限远没有那么大。由于. net程序中没有一个对象可能超过2gb,而且字符串类型使用unicode(每个字符有两个字节),所以最好的方法是1,073,741,823,但是您不太可能在32位机器上分配它。

This is one of those situations where ["If you have to ask, you're probably doing something wrong."] is the case.

这是其中一种情况,“如果你要问,你可能做错了。”]。

#2


65  

Based on my highly scientific and accurate experiment, it tops out on my machine well before 1,000,000,000 characters. (I'm still running the code below to get a better pinpoint).

基于我高度科学和准确的实验,它在我的机器上早在10亿字符之前就已经是最好的了。(我仍然在运行下面的代码以获得更好的定位)。

UPDATE: After a few hours, I've given up. Final results: Can go a lot bigger than 100,000,000 characters, instantly given System.OutOfMemoryException at 1,000,000,000 characters.

更新:几个小时后,我放弃了。最终结果:可以在给定的系统中运行超过1亿个字符。OutOfMemoryException在1000000000个字符。

using System;
using System.Collections.Generic;

public class MyClass
{
    public static void Main()
    {
        int i = 100000000;
        try
        {
            for (i = i; i <= int.MaxValue; i += 5000)
            {
                string value = new string('x', i);
                //WL(i);
            }
        }
        catch (Exception exc)
        {
            WL(i);
            WL(exc);
        }
        WL(i);
        RL();
    }

    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine(); 
    }

    private static void Break() 
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

#3


48  

Since the Length property of System.String is an Int32, I would guess that that the maximum length would be 2,147,483,647 chars (max Int32 size). If it allowed longer you couldn't check the Length since that would fail.

因为系统的长度性质。String是Int32,我猜最大长度是2147,483,647 chars (max Int32大小)。如果允许更长的时间,您就不能检查长度,因为那样会失败。

#4


23  

For anyone coming to this topic late, I could see that hitscan's "you probably shouldn't do that" might cause someone to ask what they should do…

如果有人来晚了,我可以看到hitscan的“你可能不应该这样做”可能会让别人问他们该怎么做……

The StringBuilder class is often an easy replacement. Consider one of the stream-based classes especially, if your data is coming from a file.

StringBuilder类通常是一个容易的替代品。如果数据来自一个文件,请特别考虑一个基于流的类。

The problem with s += "stuff" is that it has to allocate a completely new area to hold the data and then copy all of the old data to it plus the new stuff - EACH AND EVERY LOOP ITERATION. So, adding five bytes to 1,000,000 with s += "stuff" is extremely costly. If what you want is to just write five bytes to the end and proceed with your program, you have to pick a class that leaves some room for growth:

s += "stuff"的问题是,它必须分配一个全新的区域来保存数据,然后将所有旧数据和新数据(每次循环迭代)复制到它。因此,用s += "stuff"增加5个字节到1,000,000是非常昂贵的。如果你想要在最后写5个字节,然后继续你的程序,你必须选择一个有发展空间的类:

StringBuilder sb = new StringBuilder(5000);
for (; ; )
    {
        sb.Append("stuff");
    }

StringBuilder will auto-grow by doubling when it's limit is hit. So, you will see the growth pain once at start, once at 5,000 bytes, again at 10,000, again at 20,000. Appending strings will incur the pain every loop iteration.

当达到极限时,StringBuilder将自动增加一倍。你会看到增长的痛苦,开始的时候,5000字节,10000字节,20000字节。附加字符串将导致每次循环迭代的痛苦。

#5


6  

Strings aren't limited by integer as is commonly believed.

字符串不像通常认为的那样受到整数的限制。

Memory restrictions aside, Strings cannot have more than 230 (1,073,741,824) characters, since a 2GB limit is imposed by the Microsoft CLR (Common Language Runtime).

除了内存限制,字符串不能超过230(1073,741,824)字符,因为2GB的限制是由Microsoft CLR(公共语言运行时)施加的。

Hopefully, this may change in the future.

希望这能在未来改变。

#6


2  

200 megs... at which point your app grinds to a virtual halt, has about a gig working set memory, and the o/s starts to act like you'll need to reboot.

200 mb……这时,你的应用程序就会变成一个虚拟的停顿,有一个临时的工作设置内存,o/s开始表现得像你需要重新启动一样。

static void Main(string[] args)
{
    string s = "hello world";
    for(;;)
    {
        s = s + s.Substring(0, s.Length/10);
        Console.WriteLine(s.Length);
    }
}

12
13
14
15
16
17
18
...
158905664
174796230
192275853
211503438

#7


1  

Since String.Length is an integer (that is an alias for Int32), its size is limited to Int32.MaxValue unicode characters. ;-)

因为字符串。长度是一个整数(即Int32的别名),其大小被限制为Int32。MaxValue unicode字符。:-)