"CIImage(bitmapImageRep: self)" takes 400ms to type check?!

In a member function in an extension of NSBitmapImageRep, I'm being told by the compiler that literally the line:

CIImage(bitmapImageRep: self)

…takes over 400ms to type check. According to the compiler diagnostics from -warn-long-expression-type-checking=….

(that's of course not my original code, I just removed everything else from the line that apparently wasn't pertinent)

How on earth can that possibly take so long to type check?

What can I do about it? Normally I'd look for any type inference or overloads or similar, but in this case there's none of that. Everything is explicit and completely unambiguous.

Perhaps it's relevant that subsequent uses of CIImage - including that exact initialiser - don't take any compiler significant time at all. It appears the first use of CIImage (I have variables explicitly typed with it earlier in the function, but that's all) incurs the cost.

swift-driver version: 1.109.2 Apple Swift version 6.0 (swiftlang- clang-1600.0.20.10)

A lot of type checking work is demand-driven, and the timing instrumentation (at least historically) doesn't really separate the work that is exclusive to type-checking a particular expression from all of the work it depends on that has to be done before type-checking that expression. If you're seeing that one call to CIImage(bitmapImageRep:) is getting blamed for a lot of type checking time, but subsequent uses are cheap, it's likely that the 400ms is taken up by things like loading the necessary modules and type-checking the CIImage declaration and its members that have to happen once in order to be able to check expressions calling it, and that one line is the "lucky" line that forced all that work to happen first.


Ah, okay, that was one suspicious hypothesis I had.

Half a second is still a high cost for using CIImage, though. Is there a reasonable way for me to dig into that further and see if I can optimise whatever the real problem is? Or is it likely to be "just one of those costs", like simply loading the framework's info into the compiler?

I wonder if enabling explicitly built modules makes these timing diagnostics more reliable. From the WWDC 2024 session Demystify explicitly built modules transcript:

[With implicitly built modules,] The build system starts compilation tasks, and each separate compiler implicitly discovers, and either builds a module, if it happens to get to it first, or loads modules that are already present as it goes.

Explicitly built modules takes the implicit work of building modules and lifts it up into explicit build system tasks.

For explicitly built modules, the timeline view now contains explicit scan tasks, module compile tasks, and the original source file tasks, but now taking significantly less time.

1 Like

It does not; I'm already using them.

Sadly explicitly built modules make no apparent difference to compile times or behaviour in my current project (which isn't a large code-base - maybe 5k lines - so maybe that's to be expected).

1 Like