Comments (2)
Interesting observation!
I think there are 3 main parts that contributed to the surprising result you've got:
- Measuring performance is always tricky.
- C code is essentially faster - it's obvious, but if you hit some V8 optimization, then you're basically comparing apples to oranges... That's why V8 doesn't relay on benchmarks nowadays, instead, they measure load times for a random selection of real sites with big amount of users.
- TS2C is generating code that is far from perfect - that will hopefully be improved in future!
Tricky parts
Let's start with the tricky parts, and the most tricky part here I think is that you were probably measuring performance "the naΓ―ve way", so like this:
var start = performance.now();
for (var j = 0;j<1000000;j++) {
// measured code here
}
console.log(performance.now() - start);
But in this case, you're leaving out the interpretation part from measurement. I mean, any Javascript code must be parsed before being actually executed, right? That's the main difference between using an interpreter/JIT vs real compiler that produces a binary and then you work with that.
Parsing is in fact what takes the most of time for a JIT. And by the time execution hits performance.now()
, the whole code is obviously already compiled...
So in my opinion, the correct way to measure would be something like this:
var start = performance.now();
eval(`
for (var j = 0;j<1000000;j++) {
// measured code here
}
`);
console.log(performance.now() - start);
It took 1064ms to execute on my machine compared to ~100ms in the first example. And obviously it'll take even more if you will execute a js file with with node
executable because then you'll also take into account the node initialization time.
Btw I also tried putting eval
inside the loop - that didn't work, Chrome thought for a minute and then the tab crashed π
V8 Optimizations
Ok, now about the optimizations that you might have hit:
If a compiler sees that same variable (like colorImage
) is created over and over again inside a loop, it is a common thing to optimize this code out from the loop. Meaning that even though this code is written inside the loop, it is executed outside the loop, so only once! I actually tried to verify this assumption by manually taking this variable initialization outside of the loop, and voila, I've got exactly same ~100ms result...
In order to get similar behavior in C, you would need at least to build with -O2
, and even then C might not recognize some of optimizations that V8 is able to do, because C is operating on much lower level.
TS2C is far from perfect
I want to remind that TS2C is still work in progress and it is made by me in my spare time. If interpretation time is excluded, then you're comparing quality of compilation by V8 (which is built by a big and experienced team of developers at Google) with quality of transpilation by TS2C (so the resulting code must also be readable!)... Well π
Your capacity trick improves performance because TS2C-generated code creates a dynamic array, and then this array is reallocated to twice the current size each time it reaches current maximum capacity. So it expands like this: 2 items => 4 => 8 => 16 => 32 => 64. So essentially for 1 million executions, it will do 6 million allocations, which is 5 millions more than necessary...
In this particular case, it is indeed possible to infer the initial capacity of the array to be set to length of the parameter array. I added this to my π TODO list and will try to implement this when I have time!
Additionally there are two arrays for garbage collection, which store references to all temporary arrays which need to be deallocated when executions reaches end. Try removing those completely and putting initialization of colorImage
outside of the loop, and I think you will reach similar performance as the compiled V8 version.
Conclusion
V8 is pretty fast and has a lot of great performance optimizations, but in some cases, it cannot be used.
Main rationale for this project was to create a transpiler specifically tailored for IoT devices, as it is explained on the main project page. Low-memory microcontrollers often have just few kilobytes of memory available on board. They need to save battery energy, and for that reason, 99.9% of the time they sleep, waking up for just few milliseconds every 2-3 seconds. In such conditions, even small and optimized JS interpreters perform poorly...
from ts2c.
Hey Andrei,
Thanks for the extended explanation!
Counting the Eval time indeed makes sense, in that case, c is a very clear winner :D
Another great use case would be to use this concept for a scripting language for a game engine. Right now, Lua is a very popular scripting language for it's simple implementation and light runtime.
But this system would just beat it by an order of magnitude. I'd love to use it in a project one day!
Setting the initial capacity of the array could be a tricky problem, I guess language completeness is more important.
from ts2c.
Related Issues (20)
- Calling C Functions
- Feature: Classes (for TS at least) HOT 8
- Finishing ES3 features once and for all HOT 6
- Compiling TypeScript to C via WebAssembly HOT 2
- Please include the original code as a comment in the transpiled code HOT 12
- Memory allocation bug HOT 6
- Function.prototype.toString HOT 1
- C functions HOT 2
- Syntax errors are handled incorrectly
- Playground autocomplete keeps repeating
- Order in which properties are added is not honored
- Incorrect generation of 'free' call
- Using C++ instead of C? HOT 4
- npm - Unexpected end of JSON
- Error when combining "for in" and "for of"
- labelled statements don't work
- Ain't work HOT 1
- arguments array ain;t work
- problem with functions called main
- error with functions returning functions HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ts2c.