Vad*_*aev 1 swift swift-string
Swift 的 String 类型有一个名为 name 的属性isEmpty,指示字符串是否没有字符。
我想知道使用isEmpty空字符串文字和检查空字符串文字的相等性之间是否有任何区别。换句话说,myString.isEmpty还有比 更好吗myString == ""?
我做了一些研究并提出了以下建议:
\n\nisEmpty而不是检查字符串的长度:\n\n\n要检查字符串是否为空,请使用其
\nisEmpty属性,而不是将其中一个视图的长度与 进行比较0。与 isEmpty 不同,计算 view\xe2\x80\x99s 计数属性需要迭代字符串的元素。
Rob Napier 在 StackOverflow 上对 2015 年略有不同的问题的回答如下:
\n\n\n空字符串是唯一的空字符串,因此不应该存在
\nstring.isEmpty()返回与 不同的值的情况string == ""。当然,他们可能会花费不同的时间和内存来完成此操作。它们是否使用不同的时间和内存量是一个未描述的实现细节,但这isEmpty是检查 Swift 的首选方法(如文档所述)。
一些博客文章还建议使用isEmptyspecial而不是检查字符串的长度是否为0。
然而,这些来源都没有反对与空文字进行比较。
\n\nmyString.count == 0由于明显的性能和可读性缺陷,避免这样的构造似乎是完全合理的。我还知道它myString.isEmpty比myString == "".
不过,我很好奇与空字符串文字的比较是否不好。它真的对内存或性能有影响吗?也许 Swift 编译器现在非常智能,它会为myString.isEmpty和生成相同的二进制代码myString == ""?我的直觉是差异应该可以忽略不计,甚至不存在,但我没有证据。
我意识到这并不是一个真正的实际问题,但是如果有人可以分享一些关于这两种替代方案如何在较低级别上工作以及是否存在任何差异的见解,我将不胜感激。谢谢大家。
\n请注意,isEmpty是检查集合是否为空的首选/推荐方法,因为所有Collection类型都保证isEmpty在 O(1) 内返回(或者至少这适用于标准库集合)。相等运算符没有做出这样的保证,因此,如果您只对具有或不具有元素的集合感兴趣(例如启动处理操作),那么isEmpty绝对是正确的选择。
isEmpty现在,为了了解使用vs 与空字符串进行比较时幕后发生的情况,我们可以使用生成的程序集。
func testEmpty(_ str: String) -> Bool { str.isEmpty }
Run Code Online (Sandbox Code Playgroud)
产生以下汇编代码:
_$s3CL29testEmptyySbSSF:
0000000100002c70 push rbp
0000000100002c71 mov rbp, rsp
0000000100002c74 mov rax, rsi
0000000100002c77 shr rax, 0x38
0000000100002c7b and eax, 0xf
0000000100002c7e movabs rcx, 0xffffffffffff
0000000100002c88 and rcx, rdi
0000000100002c8b bt rsi, 0x3d
0000000100002c90 cmovae rax, rcx
0000000100002c94 test rax, rax
0000000100002c97 sete al
0000000100002c9a pop rbp
0000000100002c9b ret
Run Code Online (Sandbox Code Playgroud)
尽管
_$s3CL29testEmptyySbSSF:
0000000100002c70 push rbp
0000000100002c71 mov rbp, rsp
0000000100002c74 mov rax, rsi
0000000100002c77 shr rax, 0x38
0000000100002c7b and eax, 0xf
0000000100002c7e movabs rcx, 0xffffffffffff
0000000100002c88 and rcx, rdi
0000000100002c8b bt rsi, 0x3d
0000000100002c90 cmovae rax, rcx
0000000100002c94 test rax, rax
0000000100002c97 sete al
0000000100002c9a pop rbp
0000000100002c9b ret
Run Code Online (Sandbox Code Playgroud)
生成这个:
_$s3CL29testEqualySbSSF:
0000000100002cd0 push rbp
0000000100002cd1 mov rbp, rsp
0000000100002cd4 movabs rcx, 0xe000000000000000
0000000100002cde test rdi, rdi
0000000100002ce1 jne 0x100002cec
0000000100002ce3 cmp rsi, rcx
0000000100002ce6 jne 0x100002cec
0000000100002ce8 mov al, 0x1
0000000100002cea pop rbp
0000000100002ceb ret
0000000100002cec xor edx, edx ; XREF=_$s3CL29testEqualySbSSF+17, _$s3CL29testEqualySbSSF+22
0000000100002cee xor r8d, r8d
0000000100002cf1 pop rbp
0000000100002cf2 jmp imp___stubs__$ss27_stringCompareWithSmolCheck__9expectingSbs11_StringGutsV_ADs01_G16ComparisonResultOtF
; endp
Run Code Online (Sandbox Code Playgroud)
两个程序集都是在发布模式下生成的,并启用了所有优化。似乎对于isEmpty调用,编译器能够采取一些快捷方式,因为它知道内部String结构。
但我们可以通过使我们的函数变得通用来消除这一点:
func testEqual(_ str: String) -> Bool { str == "" }
Run Code Online (Sandbox Code Playgroud)
产生
_$s3CL29testEmptyySbxSyRzlF:
0000000100002bd0 push rbp
0000000100002bd1 mov rbp, rsp
0000000100002bd4 push r13
0000000100002bd6 push rax
0000000100002bd7 mov rax, rsi
0000000100002bda mov rcx, qword [ds:rdx+8]
0000000100002bde mov rsi, qword [ds:rcx+8]
0000000100002be2 mov r13, rdi
0000000100002be5 mov rdi, rax
0000000100002be8 call imp___stubs__$sSl7isEmptySbvgTj
0000000100002bed add rsp, 0x8
0000000100002bf1 pop r13
0000000100002bf3 pop rbp
0000000100002bf4 ret
; endp
Run Code Online (Sandbox Code Playgroud)
, 尽管
_$s3CL29testEqualySbSSF:
0000000100002cd0 push rbp
0000000100002cd1 mov rbp, rsp
0000000100002cd4 movabs rcx, 0xe000000000000000
0000000100002cde test rdi, rdi
0000000100002ce1 jne 0x100002cec
0000000100002ce3 cmp rsi, rcx
0000000100002ce6 jne 0x100002cec
0000000100002ce8 mov al, 0x1
0000000100002cea pop rbp
0000000100002ceb ret
0000000100002cec xor edx, edx ; XREF=_$s3CL29testEqualySbSSF+17, _$s3CL29testEqualySbSSF+22
0000000100002cee xor r8d, r8d
0000000100002cf1 pop rbp
0000000100002cf2 jmp imp___stubs__$ss27_stringCompareWithSmolCheck__9expectingSbs11_StringGutsV_ADs01_G16ComparisonResultOtF
; endp
Run Code Online (Sandbox Code Playgroud)
产生
_$s3CL29testEqualySbxSyRzlF:
0000000100002c00 push rbp
0000000100002c01 mov rbp, rsp
0000000100002c04 push r14
0000000100002c06 push r13
0000000100002c08 push rbx
0000000100002c09 sub rsp, 0x18
0000000100002c0d mov r14, rdx
0000000100002c10 mov r13, rsi
0000000100002c13 mov rbx, rdi
0000000100002c16 mov qword [ss:rbp+var_28], 0x0
0000000100002c1e movabs rax, 0xe000000000000000
0000000100002c28 mov qword [ss:rbp+var_20], rax
0000000100002c2c call _$sS2SSysWl
0000000100002c31 mov rcx, qword [ds:imp___got__$sSSN]
0000000100002c38 lea rsi, qword [ss:rbp+var_28]
0000000100002c3c mov rdi, rbx
0000000100002c3f mov rdx, r13
0000000100002c42 mov r8, r14
0000000100002c45 mov r9, rax
0000000100002c48 call imp___stubs__$sSysE2eeoiySbx_qd__tSyRd__lFZ
0000000100002c4d add rsp, 0x18
0000000100002c51 pop rbx
0000000100002c52 pop r13
0000000100002c54 pop r14
0000000100002c56 pop rbp
0000000100002c57 ret
; endp
Run Code Online (Sandbox Code Playgroud)
类似的结果,isEmpty代码结果是更少的汇编代码,这使得速度更快。
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |