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

Optimizing Compiler #1151

Closed
lbguilherme opened this issue Nov 13, 2014 · 9 comments
Closed

Optimizing Compiler #1151

lbguilherme opened this issue Nov 13, 2014 · 9 comments

Comments

@lbguilherme
Copy link

See: https://typescript.codeplex.com/workitem/1542 by danieljsinclair

I would like to see TypeScript become a fully fledged optimizing compiler producing minified, but optimized JavaScript code similar to what the Google Closure compiler does.

See discussion thread

In the same way we don't write ASM anymore, and we don't care if it's readable, we just want the smallest, fastest, most efficient JS code without optimizing coding practices at editing time. The compiler should take care of that.

I'm like with the near 1:1 JS output in developer mode, but as we have .map files now, and we minify for production anyway I don't think it's that important. I want to stop worrying about writing small functions and using var instead of const (where the compiler could introduce a literal in the output). I want it to optimise my const string 'tables' and concatenation. I want it to remove unnecessary/unused code, etc.

I'd like to see all this from the TypeScript compiler, without stringing together all the other technologies in my build.


I think the main issue is that true JavaScript doesn't have enough type information even by way of inference for a post-build step to achieve suitable optimization. I know that Java and .Net optimize at run time but C++ doesn't. C and C++ compilers like many others that don't produce type information need to optimize and compile time because that's where it's best.

I think TypeScript in this case falls into the C++ category because most of the type information is lost when it's turned into JavaScript and therefore true optimization can only be done well by the TS compiler.

Furthermore, a TypeScript project can be compiled as a unit rather than as an individual set of JS files. As such even things like removal of unused code is possible. Others have commented on the discussion thread that this is difficult for shared libraries which simply isn't true since the TypeScript project can consider and compile a series of TS files and produce a single output containing just the code it needs, whether one or multiple outputs.

The C++ compiler can optimize the output binary if it's working with the source files directly, but you wouldn't expect the same level of optimization of you only called into DLLs. Similarly, if you only consider the post-typed JavaScript for optimization you can't achieve optimal results.

@CyrusNajmabadi
Copy link
Contributor

I'm still curious about this bit of the original conversation:

   danieljsinclair wrote:

    ...I don't agree with @Graijkowski that we can simply string together multiple different solutions
    like Google Closure over the back of TypeScript output, as this can be problematic...

You don't specify how tool-chaining is problematic. It's the norm for most builds.

I'm not seeing what the problem is with actually using the specialized tools out there that already do a good job in this space for that purpose.

@danquirk
Copy link
Member

Much of what you'd be asking for (and the difficulties associated with that) is covered in some of the comments in #8.

@lbguilherme
Copy link
Author

@danquirk, It is not about minifing the output. This minification can be done by other tools and I don't see much advantage on doing this at the compiler. I'm talking about optimizing for speed, like function inlining, loop invariant motion, constant propagation, etc.

@CyrusNajmabadi, I agree there is other tools capable of doing the job, like Closure Compiler. But the TypeScript compiler would be able to optimize more and better because it has one thing that the Closure doesn't: Type information. Right now most of the time information is just lost after compilation.

One simple example of optimization that only this compiler can do:

function add_six(a : number) {
    return a + 4 + 2;
}

Could output:

function add_six(a) {
   return a + 6;
}

The point is that this optimization is impossible to do without the knowledge that a is a number. After all if it could be anything, then add_six("a") would output "a42" and the optimization would be ilegal.

Another simple idea if the type int were introduced:

function add(a : int, b : int) {
    return a + b;
}

Could output:

function add(a, b) {
    return (a|0) + (b|0);   // use asm.js syntax to improve speed
}

Thus: The TypeScript compiler would have advantage over any other tool out there.

@CyrusNajmabadi
Copy link
Contributor

hey @GuilhermeBernal , great examples. However, i have to say personally, that i'm very put off by them. A strong goal for me about typescript is that it is a true erasing compiler. The type information has absolutely no impact ever on your final code. Indeed, the way we represent typing issues are really as 'warnings' and not as 'errors'. That's why you can have typing warnings, and we will still generate javascript. Furthermore, we try not to touch your code at all. The only places we really do any manipulation are when you're using an ES6 construct, and compiling down to ES5. If, for example, you were doing straight TypeScript-to-ES6, then all i would want us to do is remove the type annotations, and not touch your code at all.

Moving away from that is not something i would want to do without some very very strong reasons. And simplistic constant folding simply doesn't fit the bill for me :-)

As for ASM.js transformations. I think that's definitely something that could be considered in the future. But i see that more at the point of a plugin that would affect compilation, and not something built into the language itself. But the discussion is certainly worth having.

@danquirk
Copy link
Member

I realize this issue isn't specifically about minification, but it shares a similar theme of 'the TypeScript compiler knows about types therefore it should mess with my emitted JavaScript emit by doing x,y,z' when there're an incredibly large number of circumstances some people are and are not willing to tolerate those emit differences (and what exactly those differences would be).

Some other issues with comments related to constant propagation and asm.js: #375, #720.

Cyrus has already covered some of our general philosophy here and how important preserving idiomatic JavaScript is to us (because of how important it is to so many of our users). See https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals, particular non-goals 2 and 5.

@lbguilherme
Copy link
Author

Ok, I understand. I see why a lot of people would prefer a simple readable and mostly unchanged output. It all have already been well thought and I'll close this issue. I've just started to have a look at TS and I'll learn more of it for now.

Anyway, I want to leave here the idea. Maybe it is too soon to support this but: introduce compilation flags! Things like "enable fatal errors instead of just warnings" or "enable optimizations" or maybe "enable minification". All disabled by default, but all available. It would add a lot more power to the compiler, but yes, maintenance cost increases a lot.

@jslegers
Copy link

jslegers commented Jun 22, 2017

Why was this issue closed?

Personally, I don't see much of a benefit of using TypeScript or Flow instead of JavaScript. Especially now that the ES6 standard also added class-based object-oriented programming to the language, all you'd really get from adopting TypeScript or Flow today would be the addition of static typing... and interfaces. Besides making your code look more like eg. Java code, I really don't see the benefit at all... except when using static typing to optimize the JavaScript code it produces... which is where asm.js comes in.

In environments where high performance is essential (eg. 3D rendering in the browser for browser games or GIS web apps), the current approach is to write the core code (that does the heavy lifting) in C/C++ (compiled to asm.js) and everything else in JavaScript. That means you need a really good understanding of both JavaScript (which I do) and C/C++ (which I don't) to be able to write proper code or maintain existing code for such apps, both inside and outside of the the core code.

How great would it be to be able to use one - TypeScript - codebase for such projects and compile to asm where possible and to regular JavaScript where not possible? Or to put it differently : how great would it be for a JavaScript programmer to be able to program in highly readable superset of JavaScript and have it compiled - where possible - to a highly optimized subset of JavaScript?

It seems like a win-win for everyone, really, especially if you leave it optional whether or not to compile to asm.js for developers who don't work in high performance environments and prefer readability to performance.

IMO, compilation of (a subset of) TypeScript to asm.js would be major improvement over TypeScript as it exists today. For me, it would totally be a game changer and make the difference between supporting and not supporting the adoptation of TypeScript - or Flow for that matter - at the company I work for...

While I understand that TypeScript is not intented to be compiled to asm.js, C/C++ or WebAssembly (and I expect that), the ability to export a language like Flow or TypeScript to typed AST in some way or another would be a good first start. With the TypeScript core devs not interested in this feature, it would at least open up the possibility for other teams to implement TypeScript to WebAssembly, TypeScript to C/C++ or TypeScript to asm.js conversion wherever possible.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 22, 2017

Why was this issue closed?

The person who raised it, closed it almost 3 years ago. That is why it is closed.

@jslegers
Copy link

jslegers commented Jun 22, 2017

@kitsonk I noticed. That question was actually specifically directed toward @lbguilherme, although I guess that wasn't obvious.

Those also interested in converting staticly typed variations of JavaScript to asm.js, WebAssembly or C might want to take a look at ThinScript, TurboScript or AssemblyScript.

ThinScript compiles to JavaScript, WebAssembly, and C. TurboScript compiles only to JavaScript and WebAssembly. AssemblyScript compiles to WebAssembly only.

Each of these languages have been inspired by TypeScript, and the latter is a subset of TypeScript.

I'd like to thank @RReverser for pointing me in the direction of these languages.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants