Swift 的高性能 UTF8 实现

可以考虑使用 Hitch 作为 String 的替代方案。

+-------------------------------+--------------------------+
|HitchPerformanceTests.swift    |    Faster than String    |
+-------------------------------+--------------------------+
|string iterator                |         5718.35x         |
|utf8 iterator                  |          94.80x          |
|last index of                  |          40.68x          |
|first index of                 |          18.72x          |
|contains                       |          14.38x          |
|uppercase/lowercase            |          14.25x          |
|replace occurrences of         |          10.64x          |
|append (dynamic capacity)      |          5.64x           |
|append (static capacity)       |          1.14x           |
+-------------------------------+--------------------------+

用法

Hitch 的指导愿景是帮助确保您始终处于 UTF8 字符串处理的最快路径上。 它旨在公开透明地显示可能意外减慢速度的隐藏复制操作。

Hitch 是一种引用类型,用于保存 UTF8 缓冲区数据; 可以将其视为 NSString 和 String 的混合体。 它是一个 class,可以指向共享的可变或不可变数据,并且默认情况下禁用 copyOnWrite

HalfHitch 是一种值类型,指向现有的不可变的 UTF8 数据。 如果可能,它将保留它指向的原始源。

注意:HalfHitch.unescape() 是一个例外,如果 HalfHitch 指向可变数据的一部分,它将允许您就地转义 unicode。 如果您尝试在不可变数据上调用它,它将被编码为致命错误。

Hitchable 协议提供了 HitchesHalfHitches 之间共享的所有不可变功能。 您可以为您自己的结构体遵循它,以便为任何任意 UTF8 数据提供所述功能。

作为示例,在 v0.4.0 之前的 Hitch 实现中,ExpressibleByStringLiteral 会导致底层数据的 n 个不透明副本。 现在 ExpressibleByStringLiteral 仅允许用于 StaticString(即字符串字面量),其中生成的 Hitchable 可以指向原始的、不可变的字符串数据。

默认情况下,从 StaticStrings 生成的 Hitchables 禁用 "copyOnWrite"。 这意味着尝试在从 StaticString 创建的 Hitch 上调用 mutating 方法将导致致命错误。 您可以启用 copyOnWrite,在这种情况下,在 Hitch 上调用 mutating 方法将导致在发生 mutation 之前创建一个新的、可变的数据存储。

格式化字符串

Hitch 有自己的高性能格式化字符串。 它的工作方式如下:

示例

let halfHitch = "{0} {1}" << ["hello", "world"]
let hitch = "{0} {1}" <<< ["hello", "world"]
    
XCTAssertEqual(halfHitch, "hello world")
XCTAssertEqual(hitch, "hello world")

示例

let value = Hitch("""
    {0}
    +----------+----------+----------+
    |{-??     }|{~?      }|{?       }|
    |{-?      }|{~?      }|{+?      }|
    |{-?.2    }|{~8.3    }|{+?.1    }|
    |{-1      }|{~2      }|{1       }|
    +----------+----------+----------+
    {{we no longer escape braces}}
    {These don't need to be escaped because they contain invalid characters}
    """, "This is an unbounded field", "Hello", "World", 27, 1, 2, 3, 1.0/3.0, 543.0/23.0, 99999.99999)
print(value)

输出

This is an unbounded field
+----------+----------+----------+
|Hello     |  World   |        27|
|1         |    2     |         3|
|0.33      |  23.608  |      23.6|
|Hello     |  World   |     Hello|
+----------+----------+----------+
{{we no longer escape braces}}
{These don't need to be escaped because they contain invalid characters}

无界字段
{0} 定义,没有空格或其他格式。

字段宽度
由开头的 { 和结尾的 } 之间的空格量定义。 正如您在上面的示例中看到的,这使得格式字符串中的所有内容在视觉上对齐。

左对齐
- 符号定义,例如 {-0 }。 该符号可以出现在字段中的任何位置,例如 { 0 - }

居中对齐
~ 符号定义,例如 {~0 }。 该符号可以出现在字段中的任何位置,例如 {~ 0 }

右对齐
+ 符号定义,例如 {+0 }。 该符号可以出现在字段中的任何位置,例如 { 0 +}

未命名值索引
允许使用 ?。 此值从 0 开始,并在每次在 {} 中遇到 ? 后递增。 所以 "{??? }" 是有效的,您将在此字段中获得 2 索引的值。

大括号仍然可以正常使用;
如果大括号内存在非法字符,或者大括号未能包含格式化所需的必要信息,则将按原样解释它们。

浮点精度
通过在值索引之后放置 . 来定义,后跟精度位数。 例如,{-?.4 } 表示“使用下一个值索引左对齐,精度为小数点后四位,字段宽度为 8”。

Hitch 许可证

Hitch 是在 MIT 许可证条款下分发的免费软件,如下所示。 Hitch 可以用于任何目的,包括商业目的,并且绝对免费。 没有文书工作,没有版税,没有类似 GNU 的“copyleft”限制。 只需下载并享受。

版权所有 (c) 2020 Chimera Software, LLC

特此授予任何人免费获得本软件和相关文档文件(“软件”)的副本的许可,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许向其提供本软件的人员这样做,但须符合以下条件:

上述版权声明和本许可声明应包含在本软件的所有副本或实质性部分中。

本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定用途适用性和不侵权的保证。 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同、侵权或其他方面,由软件或软件的使用或其他处理引起的或与之相关的责任。