@@ -27,15 +27,15 @@ let benchmarks = {
27
27
let parsedValue = Int ( envVar) {
28
28
modulesGraphDepth = parsedValue
29
29
} else {
30
- modulesGraphDepth = 100
30
+ modulesGraphDepth = 150
31
31
}
32
32
33
33
let modulesGraphWidth : Int
34
34
if let envVar = ProcessInfo . processInfo. environment [ " SWIFTPM_BENCHMARK_MODULES_GRAPH_WIDTH " ] ,
35
35
let parsedValue = Int ( envVar) {
36
36
modulesGraphWidth = parsedValue
37
37
} else {
38
- modulesGraphWidth = 100
38
+ modulesGraphWidth = 150
39
39
}
40
40
41
41
let packagesGraphDepth : Int
@@ -46,8 +46,6 @@ let benchmarks = {
46
46
packagesGraphDepth = 10
47
47
}
48
48
49
- let noopObservability = ObservabilitySystem . NOOP
50
-
51
49
// Benchmarks computation of a resolved graph of modules for a package using `Workspace` as an entry point. It runs PubGrub to get
52
50
// resolved concrete versions of dependencies, assigning all modules and products to each other as corresponding dependencies
53
51
// with their build triples, but with the build plan not yet constructed. In this benchmark specifically we're loading `Package.swift`
@@ -67,55 +65,120 @@ let benchmarks = {
67
65
let workspace = try Workspace ( fileSystem: localFileSystem, location: . init( forRootPackage: path, fileSystem: localFileSystem) )
68
66
69
67
for _ in benchmark. scaledIterations {
70
- try workspace. loadPackageGraph ( rootPath: path, observabilityScope: noopObservability )
68
+ try workspace. loadPackageGraph ( rootPath: path, observabilityScope: ObservabilitySystem . NOOP )
71
69
}
72
70
}
73
71
74
-
75
- // Benchmarks computation of a resolved graph of modules for a synthesized package using `loadModulesGraph` as an
76
- // entry point, which almost immediately delegates to `ModulesGraph.load` under the hood.
72
+ // Benchmarks computation of a resolved graph of modules for a trivial synthesized package using `loadModulesGraph`
73
+ // as an entry point, which almost immediately delegates to `ModulesGraph.load` under the hood.
77
74
Benchmark (
78
75
" SyntheticModulesGraph " ,
79
76
configuration: . init(
80
77
metrics: defaultMetrics,
81
78
maxDuration: . seconds( 10 ) ,
82
79
thresholds: [
83
- . mallocCountTotal: . init( absolute: [ . p90: 2500 ] ) ,
84
- . syscalls: . init( absolute: [ . p90: 0 ] ) ,
80
+ . mallocCountTotal: . init( absolute: [ . p90: 17000 ] ) ,
81
+ . syscalls: . init( absolute: [ . p90: 5 ] ) ,
85
82
]
86
83
)
87
84
) { benchmark in
88
- let targets = try ( 0 ..< modulesGraphWidth) . map { i in
89
- try TargetDescription ( name: " Target \( i) " , dependencies: ( 0 ..< min ( i, modulesGraphDepth) ) . map {
90
- . target( name: " Target \( $0) " )
91
- } )
92
- }
93
- let fileSystem = InMemoryFileSystem (
94
- emptyFiles: targets. map { " /benchmark/Sources/ \( $0. name) /empty.swift " }
85
+ try syntheticModulesGraph (
86
+ benchmark,
87
+ modulesGraphDepth: modulesGraphDepth,
88
+ modulesGraphWidth: modulesGraphWidth
95
89
)
96
- let rootPackagePath = try AbsolutePath ( validating : " /benchmark " )
90
+ }
97
91
98
- let manifest = Manifest (
99
- displayName: " benchmark " ,
100
- path: rootPackagePath,
101
- packageKind: . root( rootPackagePath) ,
102
- packageLocation: rootPackagePath. pathString,
103
- defaultLocalization: nil ,
104
- platforms: [ ] ,
105
- version: nil ,
106
- revision: nil ,
107
- toolsVersion: . v5_10,
108
- pkgConfig: nil ,
109
- providers: nil ,
110
- cLanguageStandard: nil ,
111
- cxxLanguageStandard: nil ,
112
- swiftLanguageVersions: nil
92
+ // Benchmarks computation of a resolved graph of modules for a synthesized package that includes macros,
93
+ // using `loadModulesGraph` as an entry point, which almost immediately delegates to `ModulesGraph.load` under
94
+ // the hood.
95
+ Benchmark (
96
+ " SyntheticModulesGraphWithMacros " ,
97
+ configuration: . init(
98
+ metrics: defaultMetrics,
99
+ maxDuration: . seconds( 10 ) ,
100
+ thresholds: [
101
+ . mallocCountTotal: . init( absolute: [ . p90: 8000 ] ) ,
102
+ . syscalls: . init( absolute: [ . p90: 5 ] ) ,
103
+ ]
113
104
)
105
+ ) { benchmark in
106
+ try syntheticModulesGraph (
107
+ benchmark,
108
+ modulesGraphDepth: modulesGraphDepth,
109
+ modulesGraphWidth: modulesGraphWidth,
110
+ includeMacros: true
111
+ )
112
+ }
113
+ }
114
114
115
- for _ in benchmark. scaledIterations {
116
- try blackHole (
117
- loadModulesGraph ( fileSystem: fileSystem, manifests: [ manifest] , observabilityScope: noopObservability)
118
- )
115
+ func syntheticModulesGraph(
116
+ _ benchmark: Benchmark ,
117
+ modulesGraphDepth: Int ,
118
+ modulesGraphWidth: Int ,
119
+ includeMacros: Bool = false
120
+ ) throws {
121
+ // If macros are included, modules are split in three parts:
122
+ // 1. top-level modules
123
+ // 2. macros
124
+ // 3. dependencies of macros
125
+ let macrosDenominator = includeMacros ? 3 : 1
126
+ let libraryModules : [ TargetDescription ] = try ( 0 ..< ( modulesGraphWidth / macrosDenominator) ) . map { i -> TargetDescription in
127
+ let dependencies = ( 0 ..< min ( i, modulesGraphDepth / macrosDenominator) ) . flatMap { i -> [ TargetDescription . Dependency ] in
128
+ if includeMacros {
129
+ [ . target( name: " Module \( i) " ) , . target( name: " Macros \( i) " ) ]
130
+ } else {
131
+ [ . target( name: " Module \( i) " ) ]
132
+ }
133
+ }
134
+ return try TargetDescription ( name: " Module \( i) " , dependencies: dependencies)
135
+ }
136
+
137
+ let macrosModules : [ TargetDescription ]
138
+ let macrosDependenciesModules : [ TargetDescription ]
139
+ if includeMacros {
140
+ macrosModules = try ( 0 ..< modulesGraphWidth / macrosDenominator) . map { i in
141
+ try TargetDescription ( name: " Macros \( i) " , dependencies: ( 0 ..< min ( i, modulesGraphDepth) ) . map {
142
+ . target( name: " MacrosDependency \( $0) " )
143
+ } )
144
+ }
145
+ macrosDependenciesModules = try ( 0 ..< modulesGraphWidth / macrosDenominator) . map { i in
146
+ try TargetDescription ( name: " MacrosDependency \( i) " )
119
147
}
148
+ } else {
149
+ macrosModules = [ ]
150
+ macrosDependenciesModules = [ ]
151
+ }
152
+
153
+ let modules = libraryModules + macrosModules + macrosDependenciesModules
154
+ let fileSystem = InMemoryFileSystem (
155
+ emptyFiles: modules. map {
156
+ " /benchmark/Sources/ \( $0. name) /empty.swift "
157
+ }
158
+ )
159
+ let rootPackagePath = try AbsolutePath ( validating: " /benchmark " )
160
+
161
+ let manifest = Manifest (
162
+ displayName: " benchmark " ,
163
+ path: rootPackagePath,
164
+ packageKind: . root( rootPackagePath) ,
165
+ packageLocation: rootPackagePath. pathString,
166
+ defaultLocalization: nil ,
167
+ platforms: [ ] ,
168
+ version: nil ,
169
+ revision: nil ,
170
+ toolsVersion: . v5_10,
171
+ pkgConfig: nil ,
172
+ providers: nil ,
173
+ cLanguageStandard: nil ,
174
+ cxxLanguageStandard: nil ,
175
+ swiftLanguageVersions: nil ,
176
+ targets: modules
177
+ )
178
+
179
+ for _ in benchmark. scaledIterations {
180
+ try blackHole (
181
+ loadModulesGraph ( fileSystem: fileSystem, manifests: [ manifest] , observabilityScope: ObservabilitySystem . NOOP)
182
+ )
120
183
}
121
184
}
0 commit comments