String.ToLower() 总是分配内存吗?

发布于 2024-07-13 00:38:52 字数 281 浏览 10 评论 0原文

如果所有字符都已经是小写,String.ToLower() 是否返回相同的引用(例如,不分配任何新内存)?

内存分配很便宜,但对无数短字符串进行快速检查甚至更便宜。 大多数时候,我正在使用的输入已经是小写的,但如果不是,我想这样做。

我特别使用 C# / .NET,但我的好奇心扩展到其他语言,因此请随意回答您最喜欢的语言!

注意:字符串不可变的,但这并不意味着函数总是必须返回一个新字符串,而是意味着没有任何东西可以改变它们的字符内容。

Does String.ToLower() return the same reference (e.g. without allocating any new memory) if all the characters are already lower-case?

Memory allocation is cheap, but running a quick check on zillions of short strings is even cheaper. Most of the time the input I'm working with is already lower-case, but I want to make it that way if it isn't.

I'm working with C# / .NET in particular, but my curiosity extends to other languages so feel free to answer for your favorite one!

NOTE: Strings are immutable but that does not mean a function always has to return a new one, rather it means nothing can change their character content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

迷鸟归林 2024-07-20 00:38:52

我希望如此,是的。 快速测试同意这一点(但这不是证据):

string a = "abc", b = a.ToLower();
bool areSame = ReferenceEquals(a, b); // false

一般来说,尝试与能够实现您想要的功能的比较器合作。 例如,如果您想要一个不区分大小写的字典,请使用一个:

var lookup = new Dictionary<string, int>(
    StringComparer.InvariantCultureIgnoreCase);

同样:

bool ciEqual = string.Equals("abc", "ABC",
    StringComparison.InvariantCultureIgnoreCase);

I expect so, yes. A quick test agrees (but this is not evidence):

string a = "abc", b = a.ToLower();
bool areSame = ReferenceEquals(a, b); // false

In general, try to work with comparers that do what you want. For example, if you want a case-insensitive dictionary, use one:

var lookup = new Dictionary<string, int>(
    StringComparer.InvariantCultureIgnoreCase);

Likewise:

bool ciEqual = string.Equals("abc", "ABC",
    StringComparison.InvariantCultureIgnoreCase);
哆啦不做梦 2024-07-20 00:38:52

字符串是不可变的。 String.ToLower() 将始终返回新实例,从而在每次 ToLower() 调用时生成另一个实例。

String is an immutable. String.ToLower() will always return new instance thereby generating another instance on every ToLower() call.

命硬 2024-07-20 00:38:52

Sun 的 String.toLowerCase() 的 Java 实现实际上并不总是分配新的 String。 它检查所有字符是否都是小写,如果是,则返回原始字符串。

Java implementation of String.toLowerCase() from Sun actually doesn't always allocate new String. It checks if all chars are lowercase, and if so, it returns original string.

活雷疯 2024-07-20 00:38:52

[编辑]
实习没有帮助 - 请参阅对此答案的评论。

[edit]
Interning doesn't help -- see the comments to this answer.

柠檬色的秋千 2024-07-20 00:38:52

如果您使用以下代码,它将不会分配新的内存,并且会覆盖原始字符串(这可能是也可能不是您想要的)。 它需要一个 ascii 字符串。 如果您在从您无法控制的函数返回的字符串上调用此函数,预计会发生奇怪的事情。

public static unsafe void UnsafeToLower(string asciiString)
{
    fixed (char* pstr = asciiString)
    {
        for(char* p = pstr; *p != 0; ++p)
            *p = (*p > 0x40) && (*p < 0x5b) ? (char)(*p | 0x60) : (*p);
    }
}

它花费的时间大约是 ToLowerInvariant 的 25%,并且避免了内存分配。

如果你经常在一个紧密的循环中使用 100,000 个或更多的字符串,我只会使用这样的东西。

If you use the following code it will not allocate new memory and it will overwrite the original string (this may or may not be what you want). It expects an ascii string. Expect weird things to occur if you call this on strings returned from functions you do not control.

public static unsafe void UnsafeToLower(string asciiString)
{
    fixed (char* pstr = asciiString)
    {
        for(char* p = pstr; *p != 0; ++p)
            *p = (*p > 0x40) && (*p < 0x5b) ? (char)(*p | 0x60) : (*p);
    }
}

It takes about 25% as long as ToLowerInvariant and avoids memory allocation.

I would only use something like this if you are doing say 100,000 or more strings regularly inside a tight loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文