TypeScript Version: 2.1.1 / nightly (2.2.0-dev.201xxxxx)
As described in http://stackoverflow.com/questions/36624273/investigating-long-typescript-compile-times, untyped generics can cause the TypeScript compiler to spend significantly more time type checking. It would be extremely useful to have the diagnostics report expensive type inference.
Code
This is copied from the StackOverflow example
// slow:
// ...
.flatMap((receivedObj: MyType) => {
let nextObservable: Observable<MySecondType> = this.dependingPut(receivedObj);
return nextObservable || new Observable((observer) => {
observer.next(undefined);
});
});
// fast:
.flatMap((receivedObj: MyType) => {
let nextObservable: Observable<MySecondType> = this.dependingPut(receivedObj);
return nextObservable || new Observable<MySecondType>((observer) => { // <--- use the generics!
observer.next(undefined);
});
});
Expected behavior:
Display costly type inference when diagnostics mode is enabled. Running git bisect to find performance bottlenecks is prohibitively difficult with a significantly large code base.
Actual behavior:
Only time checking is reported when using the diagnostics flag.
There is not really an easy way to tell if an inference is "costly" or not.
where is the definition of observable coming from?
I'm unsure where that definition is coming from in the Stack Overflow post. Perhaps another way to phrase this is it possible to get more granularity for the times generated by the diagnostics flag?
Open for suggestions on how to achieve that. What we know is most of the time the compiler spends checking, and most of the checking time is spent in isTypeRelatedTo. so the time the compiler spends is directly proportional to the complexity of the structural types it is operating on.
IMHO, as an end user, I just want to know which line of code/function cost most time. So maybe compiler can just collect time spent on checkSourceElement / checkDeferredNode for each node?
Will not work since one variable type can impact overall source file checking time.
@mhegazy would it be possible to calculate the complexity of a type with the compiler API? Eg could you build a tool similar to tslint which would walk the AST and compute complexity per symbol (or correct unit of abstraction)
the type itself is not an issue. you could have a very complex generic type, as long as you do not compare it to another, or you compare it to another one that has a different structure, you are fine. the issue arises from comparing two complex types that are similar but not the same. the compiler knows how to handle instantiations of the same type; it also handles things with mismatched shapes well, since it bails out fast. the problem is if they have the same shape, and they are not the same type, and the shape is complex. the only way the compiler knows how to compare them is if it compared all properties recursively.
not sure what is a good indicator.
we have done some work with the RxJS folks to solve some of these issues for RxJS. see https://github.com/ReactiveX/rxjs/pull/1475
Maybe the right way to handle this would be to log each type comparison and then the number of subtypes checked for that comparison? That would hopefully allow developers to see what is costly and figure out how to avoid those cases.
Most helpful comment
the type itself is not an issue. you could have a very complex generic type, as long as you do not compare it to another, or you compare it to another one that has a different structure, you are fine. the issue arises from comparing two complex types that are similar but not the same. the compiler knows how to handle instantiations of the same type; it also handles things with mismatched shapes well, since it bails out fast. the problem is if they have the same shape, and they are not the same type, and the shape is complex. the only way the compiler knows how to compare them is if it compared all properties recursively.
not sure what is a good indicator.
we have done some work with the RxJS folks to solve some of these issues for RxJS. see https://github.com/ReactiveX/rxjs/pull/1475