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

0 commit comments

Comments
 (0)