Skip to content

Commit 3cc427f

Browse files
add swift-dom benchmark and...
- added `swift-nio` dependency (for `ByteBuffer`) - updated `Elementary` to 0.4.1 - updated README benchmark pngs
1 parent 6199304 commit 3cc427f

File tree

12 files changed

+103
-47
lines changed

12 files changed

+103
-47
lines changed

Benchmarks/Benchmarks/Benchmarks/Benchmarks.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ let benchmarks = {
2828
"Plot" : PlotTests(),
2929
"Pointfreeco" : SwiftHTMLPFTests(),
3030
"SwiftHTMLKit" : SwiftHTMLKitTests(),
31+
"SwiftDOM" : SwiftDOMTests(),
3132
"Swim" : SwimTests(),
3233
"VaporHTMLKit" : VaporHTMLKitTests(),
3334
"Vaux (custom renderer)" : VauxTests()
@@ -49,4 +50,26 @@ let benchmarks = {
4950
}
5051
}
5152
}
53+
54+
/*let test:SwiftHTMLKitTests = SwiftHTMLKitTests()
55+
Benchmark("SwiftHTMLKit static (StaticString)") {
56+
for _ in $0.scaledIterations {
57+
blackHole(test.staticHTML())
58+
}
59+
}
60+
Benchmark("SwiftHTMLKit static ([UInt8])") {
61+
for _ in $0.scaledIterations {
62+
blackHole(test.staticHTMLUTF8Bytes())
63+
}
64+
}
65+
Benchmark("SwiftHTMLKit static ([UInt16])") {
66+
for _ in $0.scaledIterations {
67+
blackHole(test.staticHTMLUTF16Bytes())
68+
}
69+
}
70+
Benchmark("SwiftHTMLKit static (ByteBuffer)") {
71+
for _ in $0.scaledIterations {
72+
blackHole(test.staticHTMLByteBuffer())
73+
}
74+
}*/
5275
}

Benchmarks/Benchmarks/SwiftDOM/SwiftDOM.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
// Created by Evan Anderson on 10/13/24.
66
//
77

8-
/*
8+
99
import Utilities
1010
import DOM
11-
import HTML
1211

1312
package struct SwiftDOMTests : HTMLGenerator {
1413
package init() {}
@@ -23,7 +22,7 @@ package struct SwiftDOMTests : HTMLGenerator {
2322
return "\(document)"
2423
}
2524
package func dynamicHTML(_ context: HTMLContext) -> String {
26-
let qualities:(inout DOM.HTML.ContentEncoder) throws -> () = {
25+
let qualities:(inout HTML.ContentEncoder) throws -> () = {
2726
for quality in context.user.qualities {
2827
$0[.li] = quality
2928
}
@@ -32,7 +31,7 @@ package struct SwiftDOMTests : HTMLGenerator {
3231
$0[.html] {
3332
$0[.head] {
3433
$0[.meta] { $0[name: .charset] = context.charset }
35-
$0[.title] { $0[name: .title] = context.title }
34+
$0[.title] = context.title
3635
$0[.meta] {
3736
$0[name: .content] = context.meta_description
3837
$0[name: .name] = "description"
@@ -61,4 +60,12 @@ package struct SwiftDOMTests : HTMLGenerator {
6160
}
6261
return "\(document)"
6362
}
64-
}*/
63+
}
64+
65+
// required to compile
66+
extension String:HTML.OutputStreamable
67+
{
68+
}
69+
extension String:SVG.OutputStreamable
70+
{
71+
}

Benchmarks/Benchmarks/SwiftHTMLKit/SwiftHTMLKit.swift

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import Utilities
99
import SwiftHTMLKit
10+
import NIOCore
1011

1112
package struct SwiftHTMLKitTests : HTMLGenerator {
1213
package init() {}
@@ -21,8 +22,42 @@ package struct SwiftHTMLKitTests : HTMLGenerator {
2122
)
2223
)
2324
}
25+
26+
package func staticHTMLUTF8Bytes() -> [UInt8] {
27+
#htmlUTF8Bytes(
28+
#head(
29+
#title("StaticView")
30+
),
31+
#body(
32+
#h1("Swift HTML Benchmarks")
33+
)
34+
)
35+
}
36+
37+
package func staticHTMLUTF16Bytes() -> [UInt16] {
38+
#htmlUTF16Bytes(
39+
#head(
40+
#title("StaticView")
41+
),
42+
#body(
43+
#h1("Swift HTML Benchmarks")
44+
)
45+
)
46+
}
47+
48+
package func staticHTMLByteBuffer() -> ByteBuffer {
49+
#htmlByteBuffer(
50+
#head(
51+
#title("StaticView")
52+
),
53+
#body(
54+
#h1("Swift HTML Benchmarks")
55+
)
56+
)
57+
}
58+
2459
// performance notes
25-
// - maping makes unneccessary copies and hurts throughput
60+
// - maping makes unnecessary copies and hurts throughput
2661
// - interpolation hurts performance, a lot less than maping but still noticeable
2762
// - adding strings (concatenation) is faster than interpolation
2863
// - calculating the size of the result than assigning the contents in a String is significantly worse than interpolation and concatenation

Benchmarks/Benchmarks/UnitTests/UnitTests.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,38 @@ struct UnitTests {
2626
"Elementary" : ElementaryTests(),
2727
"Plot" : PlotTests(),
2828
"Pointfreeco" : SwiftHTMLPFTests(),
29-
//"SwiftDOM" : SwiftDOMTests(),
29+
"SwiftDOM" : SwiftDOMTests(),
3030
"SwiftHTMLKit" : SwiftHTMLKitTests(),
3131
"Swim" : SwimTests(),
3232
"VaporHTMLKit" : VaporHTMLKitTests(),
3333
"Vaux (custom renderer)" : VauxTests()
3434
]
35+
// Some tests fail due to:
36+
// - Plot closes void tags
37+
// - Swim doesn't minify (keeps new line characters and some whitespace); uses a dictionary for meta values; closes void tags
38+
// - Vaux is doodoo
39+
3540
@Test func staticHTML() {
3641
let expected_value:String = libraries["SwiftHTMLKit"]!.staticHTML()
37-
// Swim doesn't minify (keeps new line characters and some whitespace)
3842
for (key, value) in libraries {
3943
var string:String = value.staticHTML()
4044
if key == "Swim" {
4145
string.replace("\n", with: "")
46+
} else if key == "SwiftDOM" {
47+
string.replace("'", with: "\"")
4248
}
4349
#expect(string == expected_value, Comment(rawValue: key))
4450
}
4551
}
4652
@Test func dynamicHTML() {
4753
let context:HTMLContext = HTMLContext()
4854
let expected_value:String = libraries["SwiftHTMLKit"]!.dynamicHTML(context)
49-
// Plot closes void tags
50-
// Swim doesn't minify (keeps new line characters and some whitespace); uses a dictionary for meta values; closes void tags
51-
// Vaux is doodoo
5255
for (key, value) in libraries {
5356
var string:String = value.dynamicHTML(context)
5457
if key == "Swim" {
5558
string.replace("\n", with: "")
59+
} else if key == "SwiftDOM" {
60+
string.replace("'", with: "\"")
5661
}
5762
#expect(string == expected_value, Comment(rawValue: key))
5863
}

Benchmarks/Package.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,34 @@ let package = Package(
99
.macOS(.v14)
1010
],
1111
dependencies: [
12-
// dsls
1312
.package(url: "https://github.com/ordo-one/package-benchmark", from: "1.27.0"),
1413
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.0"),
14+
// dsls
1515
.package(name: "swift-htmlkit", path: "../"),
16-
.package(url: "https://github.com/sliemeobn/elementary", from: "0.4.0"),
17-
.package(url: "https://github.com/vapor-community/HTMLKit", from: "2.8.1"),
18-
.package(url: "https://github.com/pointfreeco/swift-html", from: "0.4.1"),
16+
.package(url: "https://github.com/sliemeobn/elementary", exact: "0.4.1"),
17+
.package(url: "https://github.com/vapor-community/HTMLKit", exact: "2.8.1"),
18+
.package(url: "https://github.com/pointfreeco/swift-html", exact: "0.4.1"),
1919
.package(url: "https://github.com/RandomHashTags/fork-bb-swift-html", branch: "main"),
20-
.package(url: "https://github.com/JohnSundell/Plot", from: "0.14.0"),
20+
.package(url: "https://github.com/JohnSundell/Plot", exact: "0.14.0"),
2121
//.package(url: "https://github.com/toucansites/toucan", from: "1.0.0-alpha.1"), // unstable
22-
.package(url: "https://github.com/robb/Swim", from: "0.4.0"),
22+
.package(url: "https://github.com/robb/Swim", exact: "0.4.0"),
2323
.package(url: "https://github.com/RandomHashTags/fork-Vaux", branch: "master"),
24-
//.package(url: "https://github.com/tayloraswift/swift-dom", from: "1.1.0"), // bad exports
24+
.package(url: "https://github.com/RandomHashTags/fork-swift-dom", branch: "master"),
2525
//.package(url: "https://github.com/TokamakUI/Tokamak", from: "0.11.1"), // swift-benchmark problem
2626

27-
.package(url: "https://github.com/vapor/leaf", from: "4.4.0"),
27+
.package(url: "https://github.com/vapor/leaf", exact: "4.4.0"),
2828

2929
// networking
30+
.package(url: "https://github.com/apple/swift-nio", from: "2.75.0"),
3031
.package(url: "https://github.com/vapor/vapor", from: "4.106.0"),
3132
.package(url: "https://github.com/hummingbird-project/hummingbird", from: "2.1.0")
3233
],
3334
targets: [
3435
.target(
3536
name: "Utilities",
37+
dependencies: [
38+
.product(name: "NIOCore", package: "swift-nio")
39+
],
3640
path: "Benchmarks/Utilities"
3741
),
3842
.target(
@@ -63,8 +67,7 @@ let package = Package(
6367
name: "TestSwiftDOM",
6468
dependencies: [
6569
"Utilities",
66-
//.product(name: "DOM", package: "swift-dom", moduleAliases: ["DOM":"SwiftDOM"]),
67-
//.product(name: "HTML", package: "swift-dom", moduleAliases: ["HTML":"SwiftDOMHTML"])
70+
.product(name: "DOM", package: "fork-swift-dom", moduleAliases: ["DOM":"SwiftDOM"])
6871
],
6972
path: "Benchmarks/SwiftDOM"
7073
),
@@ -81,7 +84,7 @@ let package = Package(
8184
dependencies: [
8285
"Utilities",
8386
.product(name: "HTMLKit", package: "swift-htmlkit", moduleAliases: ["HTMLKit":"SwiftHTMLKit"]),
84-
.product(name: "HTMLKit", package: "HTMLKit", moduleAliases: ["HTMLKit":"VaporHTMLKit"]),
87+
.product(name: "HTMLKit", package: "HTMLKit", moduleAliases: ["HTMLKit":"VaporHTMLKit"])
8588
],
8689
path: "Benchmarks/SwiftHTMLKit"
8790
),

Benchmarks/img/throughput_dynamic.png

13.3 KB
Loading

Benchmarks/img/throughput_static.png

18.1 KB
Loading

Package.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ let package = Package(
1616
),
1717
],
1818
dependencies: [
19-
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.0"),
19+
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.0"),
20+
.package(url: "https://github.com/apple/swift-nio", from: "2.75.0")
2021
],
2122
targets: [
2223
.target(
2324
name: "HTMLKitUtilities",
24-
dependencies: []
25+
dependencies: [
26+
.product(name: "NIOCore", package: "swift-nio")
27+
]
2528
),
2629
.macro(
2730
name: "HTMLKitMacros",

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,9 @@ Use a different html macro. Currently supported types (more to come with new lan
191191
## Benchmarks
192192
- Libraries tested
193193
- [BinaryBuilds/swift-html](https://github.com/BinaryBirds/swift-html) v1.7.0 (patched version [here](https://github.com/RandomHashTags/fork-bb-swift-html))
194-
- [sliemeobn/elementary](https://github.com/sliemeobn/elementary) v0.4.0
194+
- [sliemeobn/elementary](https://github.com/sliemeobn/elementary) v0.4.1
195195
- [JohnSundell/Plot](https://github.com/JohnSundell/Plot) v0.14.0
196+
- [tayloraswift/swift-dom](https://github.com/tayloraswift/swift-dom) v1.1.0 (patched version [here](https://github.com/RandomHashTags/fork-swift-dom))
196197
- [RandomHashTags/swift-htmlkit](https://github.com/RandomHashTags/swift-htmlkit) v0.6.0 (this library)
197198
- [pointfreeco/swift-html](https://github.com/pointfreeco/swift-html) v0.4.1
198199
- [robb/Swim](https://github.com/robb/Swim) v0.4.0

Sources/HTMLKit/HTMLKit.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ import HTMLKitUtilities
1111
import struct Foundation.Data
1212
#endif
1313

14-
15-
/*#if canImport(NIOCore)
1614
import struct NIOCore.ByteBuffer
17-
#endif*/
1815

1916
// MARK: StaticString equality
2017
public extension StaticString {
@@ -48,10 +45,8 @@ public macro htmlUTF8CString<T: ExpressibleByStringLiteral>(attributes: [HTMLEle
4845
public macro htmlData<T: ExpressibleByStringLiteral>(attributes: [HTMLElementAttribute] = [], xmlns: T? = nil, _ innerHTML: T...) -> Data = #externalMacro(module: "HTMLKitMacros", type: "HTMLElement")
4946
#endif
5047

51-
/*#if canImport(NIOCore)
5248
@freestanding(expression)
5349
public macro htmlByteBuffer<T: ExpressibleByStringLiteral>(attributes: [HTMLElementAttribute] = [], xmlns: T? = nil, _ innerHTML: T...) -> ByteBuffer = #externalMacro(module: "HTMLKitMacros", type: "HTMLElement")
54-
#endif*/
5550

5651
// MARK: Elements
5752

Sources/HTMLKitMacros/HTMLElement.swift

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,17 @@ import HTMLKitUtilities
1414
import struct Foundation.Data
1515
#endif
1616

17-
/*#if canImport(NIOCore)
1817
import struct NIOCore.ByteBuffer
19-
#endif*/
2018

2119
enum HTMLElement : ExpressionMacro {
2220
static func expansion(of node: some FreestandingMacroExpansionSyntax, in context: some MacroExpansionContext) throws -> ExprSyntax {
2321
let string:String = parse_macro(context: context, expression: node.macroExpansion!)
24-
var set:Set<HTMLElementType?> = [.htmlUTF8Bytes, .htmlUTF16Bytes, .htmlUTF8CString]
22+
var set:Set<HTMLElementType?> = [.htmlUTF8Bytes, .htmlUTF16Bytes, .htmlUTF8CString, .htmlByteBuffer]
2523

2624
#if canImport(Foundation)
2725
set.insert(.htmlData)
2826
#endif
2927

30-
/*#if canImport(NIOCore)
31-
set.insert(.htmlByteBuffer)
32-
#endif*/
33-
3428
if set.contains(HTMLElementType(rawValue: node.macroName.text)) {
3529
let has_interpolation:Bool = !string.ranges(of: try! Regex("\\((.*)\\)")).isEmpty
3630
guard !has_interpolation else {
@@ -53,10 +47,8 @@ enum HTMLElement : ExpressionMacro {
5347
return "Data(\(raw: bytes([UInt8](string.utf8))))"
5448
#endif
5549

56-
/*#if canImport(NIOCore)
5750
case .htmlByteBuffer:
5851
return "ByteBuffer(bytes: \(raw: bytes([UInt8](string.utf8))))"
59-
#endif*/
6052

6153
default: break
6254
}
@@ -373,9 +365,7 @@ enum HTMLElementType : String, CaseIterable {
373365
case htmlData
374366
#endif
375367

376-
/*#if canImport(NIOCore)
377368
case htmlByteBuffer
378-
#endif*/
379369

380370
case a
381371
case abbr

Tests/HTMLKitTests/HTMLKitTests.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import HTMLKit
1212
import struct Foundation.Data
1313
#endif
1414

15-
/*#if canImport(NIOCore)
1615
import struct NIOCore.ByteBuffer
17-
#endif*/
1816

1917
// MARK: Escaping HTML
2018
struct HTMLKitTests {
@@ -58,9 +56,7 @@ extension HTMLKitTests {
5856
#if canImport(Foundation)
5957
let _:Data = #htmlData("")
6058
#endif
61-
/*#if canImport(NIOCore)
6259
let _:ByteBuffer = #htmlByteBuffer("")
63-
#endif*/
6460

6561
//let bro:String = ""
6662
//let _:[UInt8] = #htmlUTF8Bytes("\(bro)")
@@ -85,11 +81,9 @@ extension HTMLKitTests {
8581
#htmlData("")
8682
}
8783
#endif
88-
/*#if canImport(NIOCore)
8984
func representation6() -> ByteBuffer {
9085
#htmlByteBuffer("")
9186
}
92-
#endif*/
9387
}
9488

9589
// MARK: Element tests

0 commit comments

Comments
 (0)