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

Feature request: inline function #661

Closed
yinhaibo01 opened this issue Sep 12, 2014 · 18 comments
Closed

Feature request: inline function #661

yinhaibo01 opened this issue Sep 12, 2014 · 18 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@yinhaibo01
Copy link

such as : inline public int add(a, b): int { return a+b; }
It's very useful for performance

@RyanCavanaugh RyanCavanaugh added Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript labels Sep 12, 2014
@RyanCavanaugh
Copy link
Member

JavaScript runtimes already automatically perform function inlining; there's no need for TypeScript to do this given the complexity of doing it correctly.

@jlennox
Copy link

jlennox commented Jun 4, 2015

Inlining at the JS level vs the runtime level may not be wholly equal, however.

http://jsperf.com/do-add-inline-test

Chrome 43.0.2357.81:
6,391,069 vs 6,714,536

Internet Explorer 11.0.9600.17801
2,079,037 vs 17,248,948

Internet Explorer 8.0.7601.17514
57,947 vs 250,837

Firefox 38.0.1
13,654,068 vs 13,444,826

Runtime inling is slower in everything but firefox, and in the latest version of internet explorer it's 8.3x faster for the JS to be inlined!

Can you provide a counter example?

@danquirk
Copy link
Member

danquirk commented Jun 4, 2015

Even if this particular example were representative of the majority of examples the results don't really suggest doing our own optimization pass is correct. Clearly in this case inlining the code doesn't actually make us faster everywhere, a meaningful number of your customers now experience slower code (even if only marginally, other cases may be worse). Then the fact that Firefox demonstrates this performance characteristic suggests it's entirely possible for IE and Chrome to eventually do the same (for this or other code patterns), at which point our optimization phase is now making your performance slower everywhere (and you only know this for each microbenchmark you manually inspect), while costing us time, adding complexity to our codebase and making the emitted JS farther from the TS that you wrote. Further, any optimization pass of this nature that you might want to make could just be handled by an existing JS optimizing tool whose sole goal is optimizing performance, something we will never be as focused on as a tool like that or the JS runtimes themselves.

The JavaScript runtimes do an immense amount of work to optimize your code, some based on static analysis, some based on runtime patterns, or something else entirely. We're simply never going to spend the same amount of effort as them on these problems (nor do we have enough information to do what they do) and the best thing we can do for your performance is to emit idiomatic code so that as they improve we emit JS that benefits from that: https://wingolog.org/archives/2011/08/02/a-closer-look-at-crankshaft-v8s-optimizing-compiler

@jlennox
Copy link

jlennox commented Jun 5, 2015

I should of said this before. I'm not for automatic inlining, but something closer to a macro statement.

Sadly, IE8 to IE11 will never become what version of IE ultimately does optimize this situation well. We'll be supporting those browsers for a very long time.

Thank you for the interesting link.

@danquirk
Copy link
Member

danquirk commented Jun 5, 2015

@jlennox see also #2721

For your case perhaps you could define a decorator called inline and a post processing task could do the work of replacing the places you've determined inlining to be advantageous.

@dorontal
Copy link

I'm totally with jlennox here: this is not just his case, but a common good programming practices case.

Sometimes we like to write tons of little helper functions (that need not incur the overhead of function calls when the code is run) and are just there for code clarity.

@rzvc
Copy link

rzvc commented Oct 23, 2016

This would be very useful for user defined type guards.

@Zorgatone
Copy link

Yes I agree. I personally need this a lot

@silbinarywolf
Copy link

I think automatic inlining similar to Golang would be beneficial,
Even basic "getter" support (ie when you simply return 1 value from a function), would be a good start.

@RyanCavanaugh
Copy link
Member

Just to reiterate: JS runtimes are extremely (extremely) good at this and you really shouldn't be worrying about this using logic acquired when writing C code.

For example, in the parser, we changed hundreds of instances from x = e; to x = f(); where f was just return e, all of which were in the hot path. We saw 0% change in runtime. 0%.

For any case where TS could determine that a function could be inlined, the JS runtime is already doing a better job of it.

@silbinarywolf
Copy link

silbinarywolf commented Mar 20, 2018

@RyanCavanaugh I really doubt you saw a 0% change in runtime in Internet Explorer and I don't think you're accounting for cases where a website needs to perform fast on IE/Edge browsers due to client restraints.

Are you able to post a link to these benchmarks? Does it cover every browser or just the Chrome?

@jlennox
Copy link

jlennox commented Mar 20, 2018

@RyanCavanaugh You can see in the result from my original test case that around Chrome 54 they either improved inlining or improved side effect free branch removal: https://jsperf.com/do-add-inline-test.

Which is great. However, I'm targeting IE8. Which now and forever has a 5x speed improvement possibility, and IE11 which has an 8x. Even in Chrome latest you can see there is some performance improvement.

I wouldn't presume that this would be decided automatically by the TypeScript compiler. Instead it would be like the C 'inline' keyword. Even C#/.NET supports something similar with MethodImplAttribute, and that's for a JIT, just like JavaScript.

@YeskaNova
Copy link

Guys, what a compiler can do, should do. If it's complicated to implement let's keep it in the backlogs until there is time for it. We can't talk about the runtime because we don't know it, we can't presume that it will be always a browser ( or a browser's JS engine in the case of node.js for example ), it could be some new startup tech in 2022, who knows.

@fluffynuts
Copy link

As a note here, I just got a significant speed increase by inlining a function called in a tight loop on node 8. So there is, imo, a reason to do this - apparently the JavaScript runtime isn't always that optimal.

@EisenbergEffect
Copy link

EisenbergEffect commented Sep 28, 2018

@RyanCavanaugh @danquirk I'd love to see this feature re-opened please 😄 The browser's ability to inline is not sufficient for a number of scenarios in the real world.

As a concrete example, I work on this product: https://www.invisionapp.com/studio One of the most critical parts of this app is a custom, WebGL-based renderer. The renderer is not currently written in TypeScript and one of the reasons it's difficult for us to justify a move to TypeScript is because of TypeScript's inability to inline specific functions. The current language it's written in supports this and it's critical for our perf scenarios.

I also believe we could make use of this in Aurelia to more liberally factor some of our complex functions to smaller functions. Inside a framework of this nature, perf is very critical.

In both the scenarios above, perf is a key competitive feature in the market and every decision is made within that context.

I realize this isn't a small feature and it's complicated, but I wanted to put another vote here based on two real, non-trivial projects that are well-known in the community.

Thanks for all the great work you all are doing!

@redhatdragon
Copy link

redhatdragon commented Oct 15, 2018

Please for the love all that is holy allow us proper inlining and a preprocessor. As a game dever this is absolutely critical especially for javascript, for both code size and runtime efficiency reasons. But please don't make inline a "suggestion" but instead forced. Or at the least include support for __forceinline like what the visual c++ compiler uses. We need full control over our code and allowing us to do things like this is just a massive help. Your already gaining traction from the game dev community. Those of us who code our own engines need as much control as possible to squeeze out as much performance as possible. Laziness is not an option in this situation.

I tip my hat to the devs of this amazing software though it's already a massive improvement over the mess that is javascript.

@danielpza
Copy link

Checkout https://github.com/LeDDGroup/typescript-transform-macros

@wongjiahau
Copy link

This feature might be also useful for React, reference: https://flexport.engineering/ending-the-debate-on-inline-functions-in-react-8c03fabd144

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests