Swift string via literal vs initializer

34 views
Skip to first unread message

Boon

unread,
Jul 2, 2015, 9:17:27 PM7/2/15
to swift-l...@googlegroups.com

In language such as Java, under the hood there is actually a difference between string obtained via string literal vs initializer.
In Swift, are they equivalent under the hood?

var string:String = ""
var string:String = String()

Jens Alfke

unread,
Jul 3, 2015, 1:44:20 PM7/3/15
to Boon, swift-l...@googlegroups.com

> On Jul 2, 2015, at 6:17 PM, Boon <bo...@nanaimostudio.com> wrote:
>
> In language such as Java, under the hood there is actually a difference between string obtained via string literal vs initializer.

What kind of difference? I haven’t used Java much in a long time, but I used to work on the Java implementation at Apple and I don’t remember there being a difference.

> In Swift, are they equivalent under the hood?

In Cocoa an NSString created from a literal tends to be* of a different subclass than one created at runtime, but that doesn’t make any difference in its behavior; you have to inspect it at runtime (e.g. in the debugger) to detect the difference.

—Jens

* I’m being vague because the behavior varies between different OS versions, due to implementation changes in the runtime and frameworks.

Boon

unread,
Jul 9, 2015, 10:44:04 AM7/9/15
to swift-l...@googlegroups.com, bo...@nanaimostudio.com

Jens Alfke

unread,
Jul 9, 2015, 12:58:28 PM7/9/15
to Boon, swift-l...@googlegroups.com
I wouldn’t call that a difference in the objects, just in the details of how they’re instantiated. The expressions have indistinguishable results.

For what it’s worth, NSString is the same way (and I’d guess native Swift strings are too), although different binaries have their own set of static literals so a string literal from one binary may not be pointer-equal to one from another. Conversely, very short strings can be stored as tagged pointers (in 64-bit) so calling a String initializer twice may return the same pointer. It’s an implementation detail, basically, since you should never use pointer equality to compare strings.

—Jens

Boon

unread,
Jul 9, 2015, 5:38:10 PM7/9/15
to swift-l...@googlegroups.com, bo...@nanaimostudio.com

Didn't say they are different in the object, but there is a difference under the hood in terms of where the object lies in memory, as indicated in the post.  In an extreme case, it can make a difference - for example, creating the string using literal vs initializer in a huge loop, the memory consumption will be quite different.

Jens Alfke

unread,
Jul 9, 2015, 5:50:32 PM7/9/15
to Boon, swift-l...@googlegroups.com
On Jul 9, 2015, at 2:38 PM, Boon <bo...@nanaimostudio.com> wrote:

Didn't say they are different in the object, but there is a difference under the hood in terms of where the object lies in memory, as indicated in the post.  

Either way the string is in the Java GC heap. There’s no difference. There is a “string constant pool” but it’s not a different place in memory; it’s conceptually just a global Map or Set object that keeps track of unique instances of strings.

In an extreme case, it can make a difference - for example, creating the string using literal vs initializer in a huge loop, the memory consumption will be quite different.

Sure, but that’s because one way explicitly creates a new object every time through the loop, while the other approach uses a single object. That’s a general optimization that has nothing to do specifically with strings.

The real question here is, “does a string literal return the same object every time it’s evaluated at runtime”, and that’s true in pretty much every language I know of.

—Jens

Boon Chew

unread,
Jul 9, 2015, 5:55:55 PM7/9/15
to Jens Alfke, swift-l...@googlegroups.com
They are not necessarily in the same memory, given that the source is different - it depends on the language you are using.  That's why I mention under the hood early on.  It would be misleading to state there is no difference, because technically if they are the same, the compiled code generated for either one should be identical.  It's definitely not the case for all languages.

Jens Alfke

unread,
Jul 9, 2015, 6:11:11 PM7/9/15
to Boon Chew, swift-l...@googlegroups.com
On Jul 9, 2015, at 2:55 PM, Boon Chew <bo...@nanaimostudio.com> wrote:

They are not necessarily in the same memory, given that the source is different - it depends on the language you are using.

It does depend on the language, but I was referring specifically to Java.

It would be misleading to state there is no difference, because technically if they are the same, the compiled code generated for either one should be identical.  It's definitely not the case for all languages.

By "difference between string obtained via string literal vs initializer”, I assumed you meant a difference in the objects. I agree that there’s a difference in the code path. Sounds like we’re in violent agreement :)

Anyway, the answer to the original question is that in Swift, as in most languages, a string literal is simply a reference to a String object that’s created at initialization time (probably when the binary containing the code is loaded.) It does not allocate memory every time it’s referenced.

—Jens
Reply all
Reply to author
Forward
0 new messages