Skip to content

Commit c7f6ad9

Browse files
committed
Improves clean Debug build time by about 30%.
Resolves issue #5123 "Charts framework takes a long time to build" (#5123) by implementing the recommendations listed at the end of the issue: - Set `Eager Linking` build setting to `Yes` for `Charts` framework target - Set `Enable Module Verifier` build setting to `No` for `Debug` builds - Set `Compilation Mode` to `Incremental` for `Debug` builds - Add `-Xfrontend -warn-long-expression-type-checking=50` (or perhaps use `100`) to `OTHER_SWIFT_FLAGS` so the Swift compiler will emit warnings for expressions that take a long time to type-check. The number after the = is the number of milliseconds threshold, above which warnings will be emitted. - Refactored the slow type-checking hotspots identified above in `ChartAnimationEasing.swift`, breaking out expressions which are slow to type-check into separate, quicker-to-type-check expressions.
1 parent e516b04 commit c7f6ad9

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

Charts.xcodeproj/project.pbxproj

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 53;
6+
objectVersion = 54;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -1034,7 +1034,8 @@
10341034
DYLIB_COMPATIBILITY_VERSION = 1;
10351035
DYLIB_CURRENT_VERSION = 1;
10361036
DYLIB_INSTALL_NAME_BASE = "@rpath";
1037-
ENABLE_MODULE_VERIFIER = YES;
1037+
EAGER_LINKING = YES;
1038+
ENABLE_MODULE_VERIFIER = NO;
10381039
ENABLE_STRICT_OBJC_MSGSEND = YES;
10391040
FRAMEWORK_VERSION = A;
10401041
GCC_NO_COMMON_BLOCKS = YES;
@@ -1051,12 +1052,14 @@
10511052
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
10521053
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
10531054
MTL_ENABLE_DEBUG_INFO = YES;
1055+
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-expression-type-checking=50";
10541056
PRODUCT_BUNDLE_IDENTIFIER = com.dcg.Charts;
10551057
PRODUCT_NAME = "$(TARGET_NAME)";
10561058
SDKROOT = macosx;
10571059
SKIP_INSTALL = YES;
10581060
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator";
10591061
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
1062+
SWIFT_COMPILATION_MODE = singlefile;
10601063
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
10611064
SWIFT_VERSION = 5.0;
10621065
TVOS_DEPLOYMENT_TARGET = 12.0;
@@ -1227,6 +1230,7 @@
12271230
DYLIB_COMPATIBILITY_VERSION = 1;
12281231
DYLIB_CURRENT_VERSION = 1;
12291232
DYLIB_INSTALL_NAME_BASE = "@rpath";
1233+
EAGER_LINKING = YES;
12301234
ENABLE_MODULE_VERIFIER = YES;
12311235
ENABLE_STRICT_OBJC_MSGSEND = YES;
12321236
FRAMEWORK_VERSION = A;
@@ -1244,6 +1248,7 @@
12441248
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
12451249
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
12461250
MTL_ENABLE_DEBUG_INFO = NO;
1251+
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-expression-type-checking=50";
12471252
PRODUCT_BUNDLE_IDENTIFIER = com.dcg.Charts;
12481253
PRODUCT_NAME = "$(TARGET_NAME)";
12491254
SDKROOT = macosx;

Source/Charts/Animation/ChartAnimationEasing.swift

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,12 @@ internal struct EasingFunctions
249249
}
250250

251251
position = position - 1.0
252-
return Double( 0.5 * (-pow(2.0, -10.0 * position) + 2.0) )
252+
253+
// compute partial result so Xcode's type-checker doesn't take too long
254+
let partialResult: Double = -pow(2.0, -10.0 * position) + 2.0
255+
256+
// took 120ms to type check before breaking out partial result, above
257+
return Double( 0.5 * partialResult )
253258
}
254259

255260
internal static let EaseInCirc = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
@@ -265,12 +270,17 @@ internal struct EasingFunctions
265270

266271
internal static let EaseInOutCirc = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
267272
var position: TimeInterval = elapsed / (duration / 2.0)
273+
274+
// calculate partial result so Swift compiler doesn't lose its mind
275+
let sqrtPartialResult: Double = sqrt(1.0 - position * position)
268276
if position < 1.0
269277
{
270-
return Double( -0.5 * (sqrt(1.0 - position * position) - 1.0) )
278+
// was 800ms to type check with inlined sqrt calculation, from above
279+
return Double( -0.5 * (sqrtPartialResult - 1.0) )
271280
}
272281
position -= 2.0
273-
return Double( 0.5 * (sqrt(1.0 - position * position) + 1.0) )
282+
// was 1500ms to type check with inlined sqrt calculation, from above
283+
return Double( 0.5 * (sqrtPartialResult + 1.0) )
274284
}
275285

276286
internal static let EaseInElastic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
@@ -328,13 +338,23 @@ internal struct EasingFunctions
328338
return Double( -0.5 * (pow(2.0, 10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p)) )
329339
}
330340
position -= 1.0
331-
return Double( pow(2.0, -10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p) * 0.5 + 1.0 )
341+
342+
// Break out partial result so the Swift compiler doesn't lose its mind
343+
let sinPartialResult: Double = sin((position * duration - s) * (2.0 * Double.pi) / p)
344+
345+
// Original expression here, with the expression above inlined, took 600ms to type check
346+
return Double( pow(2.0, -10.0 * position) * sinPartialResult * 0.5 + 1.0 )
332347
}
333348

334349
internal static let EaseInBack = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
335350
let s: TimeInterval = 1.70158
336351
var position: TimeInterval = elapsed / duration
337-
return Double( position * position * ((s + 1.0) * position - s) )
352+
353+
// Break out partial result so the Swift compiler doesn't lose its mind
354+
let partialResult: Double = ((s + 1.0) * position - s)
355+
356+
// Original expression here, with partialResult inlined, took 260ms to type check
357+
return Double( position * position * partialResult )
338358
}
339359

340360
internal static let EaseOutBack = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in

0 commit comments

Comments
 (0)