Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagnostics for costly type inference #13057

Closed
pspeter3 opened this issue Dec 20, 2016 · 7 comments
Closed

Diagnostics for costly type inference #13057

pspeter3 opened this issue Dec 20, 2016 · 7 comments
Labels
Needs More Info The issue still hasn't been fully clarified

Comments

@pspeter3
Copy link

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.

@mhegazy
Copy link
Contributor

mhegazy commented Dec 21, 2016

There is not really an easy way to tell if an inference is "costly" or not.

where is the definition of observable coming from?

@pspeter3
Copy link
Author

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?

@mhegazy
Copy link
Contributor

mhegazy commented Dec 22, 2016

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.

@DanielRosenwasser DanielRosenwasser added the Needs More Info The issue still hasn't been fully clarified label Dec 22, 2016
@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented Dec 22, 2016

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.

@pspeter3
Copy link
Author

@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)

@mhegazy
Copy link
Contributor

mhegazy commented Dec 22, 2016

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 ReactiveX/rxjs#1475

@pspeter3
Copy link
Author

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.

@mhegazy mhegazy closed this as completed Apr 19, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs More Info The issue still hasn't been fully clarified
Projects
None yet
Development

No branches or pull requests

4 participants