From ced9c53ec8a5e1a73facf58802c02c2b36c51558 Mon Sep 17 00:00:00 2001 From: Maciej Trybilo Date: Mon, 12 Feb 2024 12:26:56 +0100 Subject: [PATCH] Optimise parsing by removing excessive copying. (#278) * Optimise parsing by removing excessive copying. * Add benchmark --------- Co-authored-by: Joannis Orlandos --- Benchmarks/.vscode/launch.json | 28 + .../XMLCoderBenchmarks/Benchmark.swift | 14 + .../XMLCoderBenchmarks/XMLDecode.swift | 1136 +++++++++++++++++ Benchmarks/Package.resolved | 77 ++ Benchmarks/Package.swift | 26 + .../XMLCoder/Auxiliaries/KeyedStorage.swift | 25 +- .../Auxiliaries/XMLCoderElement.swift | 23 +- XMLCoder.podspec | 9 +- 8 files changed, 1311 insertions(+), 27 deletions(-) create mode 100644 Benchmarks/.vscode/launch.json create mode 100644 Benchmarks/Benchmarks/XMLCoderBenchmarks/Benchmark.swift create mode 100644 Benchmarks/Benchmarks/XMLCoderBenchmarks/XMLDecode.swift create mode 100644 Benchmarks/Package.resolved create mode 100644 Benchmarks/Package.swift diff --git a/Benchmarks/.vscode/launch.json b/Benchmarks/.vscode/launch.json new file mode 100644 index 00000000..378082ec --- /dev/null +++ b/Benchmarks/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "configurations": [ + { + "type": "lldb", + "request": "launch", + "sourceLanguages": [ + "swift" + ], + "args": [], + "cwd": "${workspaceFolder:Benchmarks}", + "name": "Debug XMLCoderBenchmarks", + "program": "${workspaceFolder:Benchmarks}/.build/debug/XMLCoderBenchmarks", + "preLaunchTask": "swift: Build Debug XMLCoderBenchmarks" + }, + { + "type": "lldb", + "request": "launch", + "sourceLanguages": [ + "swift" + ], + "args": [], + "cwd": "${workspaceFolder:Benchmarks}", + "name": "Release XMLCoderBenchmarks", + "program": "${workspaceFolder:Benchmarks}/.build/release/XMLCoderBenchmarks", + "preLaunchTask": "swift: Build Release XMLCoderBenchmarks" + } + ] +} \ No newline at end of file diff --git a/Benchmarks/Benchmarks/XMLCoderBenchmarks/Benchmark.swift b/Benchmarks/Benchmarks/XMLCoderBenchmarks/Benchmark.swift new file mode 100644 index 00000000..f378a35c --- /dev/null +++ b/Benchmarks/Benchmarks/XMLCoderBenchmarks/Benchmark.swift @@ -0,0 +1,14 @@ +import Benchmark + +let benchmarks = { + Benchmark( + "XMLDecoder", + configuration: .init( + metrics: [ + .throughput + ] + ) + ) { benchmark in + try runXMLDecoder() + } +} \ No newline at end of file diff --git a/Benchmarks/Benchmarks/XMLCoderBenchmarks/XMLDecode.swift b/Benchmarks/Benchmarks/XMLCoderBenchmarks/XMLDecode.swift new file mode 100644 index 00000000..c113b0d5 --- /dev/null +++ b/Benchmarks/Benchmarks/XMLCoderBenchmarks/XMLDecode.swift @@ -0,0 +1,1136 @@ +import XMLCoder +import Foundation + +struct Companies: Codable { + struct Company: Codable { + struct Address: Codable { + let street: String + let city: String + let state: String + let zip: String + } + + let name: String + let address: Address + let ceo: String + let dateCreated: Date + } + + let company: [Company] +} + +func runXMLDecoder() throws { + let decoder = XMLDecoder() + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + decoder.dateDecodingStrategy = .formatted(formatter) + let data = try decoder.decode(Companies.self, from: testData.data(using: .utf8)!) + guard data.company.count == 100 else { + fatalError("Invalid test expectation") + } +} + +fileprivate let testData = """ + + + Known International S.A +
+ 7246 Anthony + Bel Air + Montana + NJ50096 +
+ Calista Harr + 2017-05-12 +
+ + Ps +
+ 4932 Borsden Circle + Kenosha + New Hampshire + NY36570 +
+ Lucia Corey + 1976-09-04 +
+ + Causes Software LLC +
+ 2743 Rushmere Road + Downey + Tennessee + NV31214 +
+ Nelson Ouellette + 2001-01-16 +
+ + Blah Mutual Corp +
+ 2110 Turncroft Lane + Yonkers + Florida + WA20155 +
+ Tereasa Pettit + 2001-01-03 +
+ + Sciences +
+ 0476 Redthorn Road + Eugene + South Carolina + KY08303 +
+ Wynona King + 2022-11-26 +
+ + Cs Company +
+ 5463 Knowle Circle + Cathedral City + Florida + NM06696 +
+ Grover Tafoya + 1975-02-23 +
+ + Emperor Stores Inc +
+ 8690 Gould Road + Toledo + Hawaii + LA95381 +
+ Verna Bowler + 1978-10-20 +
+ + Garlic Energy LLC +
+ 7112 Goughs Avenue + Lancaster + New Mexico + FL09641 +
+ Vi Thrash + 1988-04-14 +
+ + Massive Stores GmbH +
+ 2534 Bosden Street + Bonita Springs + Oklahoma + OH07004 +
+ Tandy Mcbee + 1992-11-11 +
+ + Surf Holdings Company +
+ 9698 Neild + Fargo + Colorado + AL70062 +
+ Leopoldo Lowry + 2018-10-12 +
+ + Path Ltd +
+ 6727 Kelson Circle + Hollywood + Louisiana + MD44169 +
+ Lesli Dietrich + 1994-12-06 +
+ + Detected GmbH +
+ 5810 Horderns Circle + Palm Springs + Arkansas + IA57090 +
+ Karla Hyland + 2017-02-02 +
+ + Spies Stores +
+ 0683 Marland Circle + Sarasota + New Mexico + FL80124 +
+ Perla Mcbee + 2004-09-19 +
+ + Tech LLC +
+ 4788 Back Avenue + Gainesville + Utah + WY86585 +
+ Tomas Woo + 2005-07-29 +
+ + Rf Corporation +
+ 3037 Pear + Lexington + Georgia + TX26071 +
+ Jeanelle Sander + 1987-08-06 +
+ + Soap Stores A.G +
+ 6559 Back Street + Albany + Maine + NV91407 +
+ Dominica Peeples + 1995-03-01 +
+ + Professionals Corporation +
+ 3441 Rodney Circle + McHenry + New Mexico + NE76752 +
+ Jesica Weathers + 2011-09-13 +
+ + Manufactured Corp +
+ 9543 Gosling Circle + Syracuse + New Mexico + OK70595 +
+ Arnette Bishop + 1991-04-27 +
+ + Highways S.A +
+ 7666 Deacons + Gastonia + Pennsylvania + ND06984 +
+ Rachell Horst + 1988-12-03 +
+ + Utils +
+ 8894 Brentnor Road + Winter Haven + Vermont + NY22467 +
+ Carlie Fahey + 2020-12-09 +
+ + Figures +
+ 8372 Wyngate Avenue + Burlington + Maryland + OK50868 +
+ Shameka Zink + 1977-09-27 +
+ + Classics Software S.A +
+ 8546 Cheam Avenue + Augusta + Connecticut + CO60895 +
+ Elodia Thornburg + 2019-09-03 +
+ + Journalists SIA +
+ 9174 Hob + Topeka + Oklahoma + CO68708 +
+ Lachelle Gagnon + 1992-10-05 +
+ + Acc Software +
+ 0072 Aber Road + Charlotte + New Hampshire + TN90616 +
+ Carlita Owens + 2003-05-17 +
+ + Lime Energy Company +
+ 3694 Bollin + Orange + Idaho + MD26937 +
+ Solange Cota + 1977-04-27 +
+ + Watched Stores +
+ 4709 Brazley Lane + Abilene + Rhode Island + PA99377 +
+ Essie Farley + 2000-10-14 +
+ + Combat +
+ 4089 Canada Road + Fresno + North Carolina + ME51644 +
+ Cristine Anthony + 1988-05-24 +
+ + Blackberry Inc +
+ 3767 Badminton Road + Chicago + Virginia + WI50400 +
+ Lilliana Chambers + 2007-07-06 +
+ + Midwest A.G +
+ 7224 Globe Street + College Station + Massachusetts + AK01157 +
+ Shizuko Dominquez + 2021-05-05 +
+ + Rebecca Energy S.A +
+ 8854 Cinamon + Salem + Maine + TX09054 +
+ Wilber Eskridge + 1989-07-28 +
+ + Psychiatry Industries Company +
+ 5386 Woodseats Street + Raleigh + Alaska + NJ72141 +
+ Tobias Dion + 1976-02-21 +
+ + Counts International +
+ 9618 Silverhey Avenue + Sioux City + New Jersey + IN29960 +
+ Temple Murphy + 1974-11-11 +
+ + Christina International SIA +
+ 5463 Gillbrook Lane + Melbourne + Virginia + VA80719 +
+ Barbara Sonnier + 2005-03-03 +
+ + Antenna Energy Pte. Ltd +
+ 4029 Honeysuckle Lane + Erie + Alaska + SC98046 +
+ Henry Clem + 1988-03-22 +
+ + Boc Holdings B.V +
+ 3032 Orrell Road + Medford + West Virginia + AK60134 +
+ Lia Rasmussen + 1979-04-18 +
+ + Actual Mutual B.V +
+ 7057 Deer Street + Fremont + North Carolina + NE26947 +
+ Normand Ricker + 1991-07-23 +
+ + Si B.V +
+ 5739 Nunthorpe Lane + Melbourne + Maryland + AL13695 +
+ Shawnee Turnbull + 1999-01-30 +
+ + Hotmail Company +
+ 6908 Unwin Circle + Killeen + Virginia + TX65173 +
+ Lyndon Stone-Cochran + 2004-03-30 +
+ + Plug Energy A.G +
+ 3809 Sunlight Lane + Trenton + Minnesota + VT17069 +
+ Ernie Lovett + 1973-09-15 +
+ + Characters Holdings LLC +
+ 2589 Derwen Street + Cedar Rapids + North Carolina + OH70168 +
+ Arica Sherrod + 1970-01-30 +
+ + Standing International SIA +
+ 2908 Bernisdale + Henderson + Indiana + TX98606 +
+ Beulah Hart + 2023-07-15 +
+ + Ht Energy Ltd +
+ 3554 Racecourse Avenue + Clarksville + Oklahoma + SD99739 +
+ Modesto Hinson + 2016-09-14 +
+ + Affordable Software LLC +
+ 8955 Erica + Santa Maria + Colorado + SD00318 +
+ Alvaro Huntley + 1994-04-27 +
+ + Devon LLC +
+ 1097 Blair Street + Charlotte + Wisconsin + MT01111 +
+ Chasity Tuck + 1985-04-18 +
+ + Wanted Software +
+ 1662 Eastbourne Road + Frederick + Ohio + OH72441 +
+ Tammi Mcnamara + 1975-11-22 +
+ + Hotel Mutual A.G +
+ 6850 Dell Circle + Victorville + Arkansas + AL38687 +
+ Dorla Williams + 1977-12-09 +
+ + Lycos +
+ 4288 Haley + Racine + Texas + MD04440 +
+ Armanda Koehler + 2003-09-13 +
+ + Approaches Industries S.A +
+ 3962 Baron Lane + Elkhart + New Jersey + NV91449 +
+ Lidia Almond + 2023-02-16 +
+ + Downloadable S.A +
+ 7370 Merlyn Lane + Seattle + Tennessee + MO51368 +
+ Roseanne Benefield + 2018-09-19 +
+ + Abstract GmbH +
+ 5235 Euston Street + Memphis + Montana + MD46124 +
+ Ardith Darling + 1979-09-28 +
+ + Lease Corp +
+ 4506 Katherine + Evansville + New York + KS94523 +
+ Dollie Fallon + 2001-03-16 +
+ + Lesser Ltd +
+ 2169 Braddyll Lane + Memphis + Missouri + MD76541 +
+ Yasuko Coffey + 2001-09-26 +
+ + Dx Software Corporation +
+ 1445 Upton Circle + Daly City + Texas + IA72709 +
+ Velva Rock + 2003-01-03 +
+ + Webster International +
+ 5040 Oakdale + Coral Springs + Minnesota + ME87181 +
+ Haywood Woodruff + 2006-09-24 +
+ + Surgical Company +
+ 6169 Bilbrook Road + Chula Vista + New Jersey + ID65614 +
+ Rolf Schiller + 1995-01-24 +
+ + Concepts Stores +
+ 8402 Peel + Pompano Beach + Mississippi + TX93462 +
+ Kacey Treadwell + 2003-02-08 +
+ + Curriculum Industries Corporation +
+ 7134 Back Circle + Antioch + Montana + MA13056 +
+ Wilson Skeen + 1998-11-22 +
+ + Verzeichnis Software Corp +
+ 6441 Martlew Circle + Brownsville + Nevada + CO68926 +
+ Latrice Fugate + 1996-02-14 +
+ + Compilation International LLC +
+ 4372 Roseleigh Lane + Syracuse + Colorado + WV67698 +
+ Yan Stearns + 1980-01-19 +
+ + Exit Mutual Inc +
+ 9096 War + Santa Cruz + Idaho + TX77737 +
+ Robert Ledford + 2017-04-23 +
+ + Inputs International Pte. Ltd +
+ 3914 Jowett Street + Costa Mesa + Massachusetts + NH47843 +
+ Adolph Steward + 1984-09-18 +
+ + Recover Software Company +
+ 9303 Pentland Street + Huntington + Idaho + AZ57314 +
+ Lore Mcleod + 1979-08-06 +
+ + Emma Pte. Ltd +
+ 2835 Hollowood + Palmdale + Georgia + NV09689 +
+ Shannan Usher + 2008-08-09 +
+ + Suppliers International A.G +
+ 9112 Pine Lane + San Antonio + New Hampshire + MD48555 +
+ Criselda Booth-Joyner + 2003-10-10 +
+ + Tba +
+ 2521 Pritchard Circle + Syracuse + Connecticut + RI89406 +
+ Weston Thomsen + 2018-07-18 +
+ + Leonard SIA +
+ 9741 Casson Street + Akron + Maine + OR53897 +
+ Jerry Gilliland + 1988-10-25 +
+ + Mae Mutual Corporation +
+ 5737 Roundwood Lane + Appleton + Nebraska + ME20559 +
+ Sherill Rayford + 1981-09-15 +
+ + Pc A.G +
+ 0628 Balshaw Street + Pittsburgh + Arkansas + OR01573 +
+ Amiee Solis + 2012-05-30 +
+ + Mathematics Software GmbH +
+ 1776 Rough Lane + Fort Wayne + Massachusetts + HI71966 +
+ Garrett Dickerson + 2022-11-17 +
+ + Ski Industries Pte. Ltd +
+ 2628 Unwick Circle + Trenton + Delaware + VT94732 +
+ Pei Frederick + 2003-03-20 +
+ + Rides Software Ltd +
+ 4232 Warley Street + Harlingen + Massachusetts + NM74100 +
+ Tomi Florence + 2019-07-08 +
+ + Relax S.A +
+ 8747 Rangemore + Stockton + Wisconsin + VT83769 +
+ Anthony Pichardo + 1973-12-09 +
+ + Requests +
+ 9131 Searby Lane + Macon + Iowa + MO91097 +
+ Carola Olivas + 1989-09-24 +
+ + Post International Inc +
+ 2290 Cinamon Street + Utica + Maine + DE15362 +
+ Ngoc Nagel + 1996-02-14 +
+ + Read Holdings Inc +
+ 0523 Birchbrook + Hemet + Texas + TN70174 +
+ Jeni Boisvert-Lara + 2002-02-28 +
+ + Prague Company +
+ 3273 Great + Oceanside + Arkansas + AK14991 +
+ Ariel Dempsey + 1971-09-30 +
+ + Aspect Mutual +
+ 5377 McKean Road + Boise + Rhode Island + UT99066 +
+ Flossie Hester + 2004-01-31 +
+ + Stocks Software Company +
+ 5495 Kenstford Road + San Antonio + Tennessee + LA67160 +
+ Ahmad Ambrose + 2014-01-15 +
+ + Indicated Stores Corporation +
+ 4063 Cleworth Circle + GreenBay + Nebraska + OR99052 +
+ Alica Wiese + 1997-06-16 +
+ + Remedies Ltd +
+ 8247 Crosshill + Orem + Florida + AR41015 +
+ Selene Tidwell + 2022-10-12 +
+ + Reasonably B.V +
+ 3075 Mottram Road + Oakland + South Carolina + PA56722 +
+ Dianne Mayes + 2016-11-13 +
+ + Ntsc Corp +
+ 1050 Davenport Circle + Saint Paul + Delaware + VT63860 +
+ Marta Reeves + 1971-05-03 +
+ + Showtimes Holdings Corp +
+ 4732 Glynne Avenue + Arvada + North Dakota + CT17298 +
+ Flor Oden + 1978-01-02 +
+ + Rangers Corp +
+ 6565 Higher Road + Torrance + West Virginia + KS21411 +
+ Jaqueline Kyle + 1978-09-18 +
+ + Const Corporation +
+ 7997 Park + Vero Beach + Delaware + AZ10633 +
+ Toi Yount + 1999-08-22 +
+ + Math Software B.V +
+ 6135 Wilmur + Lowell + Kentucky + IA02702 +
+ Kristie Marvin + 1979-06-23 +
+ + Billing Industries SIA +
+ 4766 Netherfield Street + Roseville + Florida + GA25266 +
+ Ardell Clemmons + 2010-10-20 +
+ + Uc Mutual B.V +
+ 1859 Orphanage Street + Modesto + Alabama + AR40959 +
+ Jill Tillery + 2012-12-15 +
+ + Craps LLC +
+ 3227 Gunnery + Springfield + Texas + GA87508 +
+ Alphonso Bussey-Ventura + 1983-03-24 +
+ + Owner Holdings B.V +
+ 2116 Back + San Antonio + Oklahoma + MI20909 +
+ Vivienne Dew + 1991-05-24 +
+ + Talks A.G +
+ 2354 Rylands Road + Montgomery + Wisconsin + OH52140 +
+ Edra Krieger + 2013-12-03 +
+ + Facilitate Software S.A +
+ 3668 Ludgate + Irvine + Missouri + ID47086 +
+ Shad Christie + 1987-03-04 +
+ + Baking Holdings GmbH +
+ 6743 Bracken + Hayward + Michigan + MI04293 +
+ Emmitt Keeton + 1985-08-15 +
+ + Nintendo B.V +
+ 3842 Godward Circle + Hayward + Nevada + TN22890 +
+ Gertie Haas + 2023-09-10 +
+ + Leonard Inc +
+ 4441 Love + Brownsville + Indiana + PA51846 +
+ Lindy Kincaid + 2015-06-27 +
+ + Rid Pte. Ltd +
+ 9709 Sandfield Road + Bradenton + Michigan + WA89319 +
+ Carlita Mckay + 2012-01-24 +
+ + Knows Industries +
+ 8554 Shudehill Street + Champaign + Indiana + CO25149 +
+ Mallie Schmitz + 2020-09-18 +
+ + Apparently S.A +
+ 6465 Isherwood Road + Riverside + Tennessee + OH58938 +
+ Lesha Watkins + 1985-03-28 +
+ + Fellow International GmbH +
+ 8951 Anaconda Street + Worcester + Louisiana + TN45678 +
+ Enriqueta Sanford + 1978-10-13 +
+ + Bestsellers Holdings +
+ 1844 Graham Road + Utica + Michigan + AZ89250 +
+ Catrice Brinson + 1978-04-03 +
+
+""" \ No newline at end of file diff --git a/Benchmarks/Package.resolved b/Benchmarks/Package.resolved new file mode 100644 index 00000000..c4d6edda --- /dev/null +++ b/Benchmarks/Package.resolved @@ -0,0 +1,77 @@ +{ + "pins" : [ + { + "identity" : "hdrhistogram-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/HdrHistogram/hdrhistogram-swift", + "state" : { + "revision" : "a69fa24d7b70421870cafa86340ece900489e17e", + "version" : "0.1.2" + } + }, + { + "identity" : "package-benchmark", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/package-benchmark.git", + "state" : { + "revision" : "ddf6c1ae01e139120bcdb917ece52819ee69d47a", + "version" : "1.22.1" + } + }, + { + "identity" : "package-jemalloc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/package-jemalloc", + "state" : { + "revision" : "e8a5db026963f5bfeac842d9d3f2cc8cde323b49", + "version" : "1.0.0" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser", + "state" : { + "revision" : "c8ed701b513cf5177118a175d85fbbbcd707ab41", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics", + "state" : { + "revision" : "cd142fd2f64be2100422d658e7411e39489da985", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-system", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-system", + "state" : { + "revision" : "025bcb1165deab2e20d4eaba79967ce73013f496", + "version" : "1.2.1" + } + }, + { + "identity" : "texttable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/TextTable", + "state" : { + "revision" : "a27a07300cf4ae322e0079ca0a475c5583dd575f", + "version" : "0.0.2" + } + } + ], + "version" : 2 +} diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift new file mode 100644 index 00000000..eed657cf --- /dev/null +++ b/Benchmarks/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 5.7 +import PackageDescription + +let package = Package( + name: "benchmarks", + platforms: [ + .macOS("14"), + ], + dependencies: [ + .package(path: "../"), + .package(url: "https://github.com/ordo-one/package-benchmark.git", from: "1.22.0"), + ], + targets: [ + .executableTarget( + name: "XMLCoderBenchmarks", + dependencies: [ + .product(name: "Benchmark", package: "package-benchmark"), + .product(name: "XMLCoder", package: "XMLCoder"), + ], + path: "Benchmarks/XMLCoderBenchmarks", + plugins: [ + .plugin(name: "BenchmarkPlugin", package: "package-benchmark") + ] + ), + ] +) \ No newline at end of file diff --git a/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift b/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift index 3424266e..808a38dc 100644 --- a/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift +++ b/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift @@ -59,6 +59,11 @@ struct KeyedStorage { return try buffer.compactMap(transform) } + mutating func reserveCapacity(_ capacity: Int) { + buffer.reserveCapacity(capacity) + keyMap.reserveCapacity(capacity) + } + init() {} } @@ -75,23 +80,3 @@ extension KeyedStorage: CustomStringConvertible { return "[\(result)]" } } - -extension KeyedStorage where Key == String, Value == Box { - func merge(element: XMLCoderElement) -> KeyedStorage { - var result = self - - let hasElements = !element.elements.isEmpty - let hasAttributes = !element.attributes.isEmpty - let hasText = element.stringValue != nil - - if hasElements || hasAttributes { - result.append(element.transformToBoxTree(), at: element.key) - } else if hasText { - result.append(element.transformToBoxTree(), at: element.key) - } else { - result.append(SingleKeyedBox(key: element.key, element: NullBox()), at: element.key) - } - - return result - } -} diff --git a/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift b/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift index 38fdc053..0d73a2ea 100644 --- a/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift +++ b/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift @@ -115,9 +115,26 @@ struct XMLCoderElement: Equatable { let attributes = KeyedStorage(self.attributes.map { attribute in (key: attribute.key, value: StringBox(attribute.value) as SimpleBox) }) - let storage = KeyedStorage() - let elements = self.elements.reduce(storage) { $0.merge(element: $1) } - return KeyedBox(elements: elements, attributes: attributes) + + var storage = KeyedStorage() + // storage.reserveCapacity(self.elements) + + for element in self.elements { + + let hasElements = !element.elements.isEmpty + let hasAttributes = !element.attributes.isEmpty + let hasText = element.stringValue != nil + + if hasElements || hasAttributes { + storage.append(element.transformToBoxTree(), at: element.key) + } else if hasText { + storage.append(element.transformToBoxTree(), at: element.key) + } else { + storage.append(SingleKeyedBox(key: element.key, element: NullBox()), at: element.key) + } + } + + return KeyedBox(elements: storage, attributes: attributes) } func toXMLString( diff --git a/XMLCoder.podspec b/XMLCoder.podspec index b6b75583..40ef21c8 100644 --- a/XMLCoder.podspec +++ b/XMLCoder.podspec @@ -1,20 +1,21 @@ Pod::Spec.new do |s| s.name = "XMLCoder" - s.version = "0.14.0" + s.version = "0.17.1" s.summary = "XMLEncoder & XMLDecoder using the Codable protocol in Swift" s.description = "XMLCoder allows Swift Codable-conforming objects to be translated to and from XML" - s.homepage = "https://github.com/MaxDesiatov/XMLCoder" + s.homepage = "https://github.com/CoreOffice/XMLCoder" s.license = { :type => "MIT", :file => "LICENSE" } s.authors = { "Shawn Moore" => "sm5@me.com", - "Max Desiatov" => "max@desiatov.com" + "Max Desiatov" => "max@desiatov.com", + "Joannis Orlandos" => "joannis@orlandos.nl" } s.watchos.deployment_target = "2.0" s.ios.deployment_target = "9.0" s.tvos.deployment_target = "9.0" s.osx.deployment_target = "10.11" s.swift_versions = ["5.1"] - s.source = { :git => "https://github.com/MaxDesiatov/XMLCoder.git", :tag => s.version.to_s } + s.source = { :git => "https://github.com/CoreOffice/XMLCoder.git", :tag => s.version.to_s } s.source_files = "Sources/XMLCoder/**/*.swift" s.requires_arc = true end