-
Notifications
You must be signed in to change notification settings - Fork 97
Bring true coroutines(fiber) to ayo in core code? #19
Comments
Fibers are largely superseded by async/await and solve a problem ayo doesn't really have. |
Actually, I don't want to write extra keywords in code. |
@benjamingr Fibers‘s performance is much better than async/await and it has no infection. |
@ShiningRay you needn't write extra keywords in code if you know how it works. |
Fibers are not faster, look at the benchmarks bluebird always beat fibers since 2013. Also, we should stick with standard approaches (promises/async await) rather than go against the language specification. |
As a former fibers user, I too believe that async/await has essentially supplanted fibers: and async/await has the advantage that it does not need additional VM-level work from the project, and fits neatly into other components of the language (specially Promises, which are now quite widespread), making it more compatible with the existing ecosystem. That's my 2c at least :) |
Yeah, the interop of async/await with all existing promise-based code is a huge advantage. Fibers are neat but ultimately incompatible with the vast majority of existing modules. |
Maybe there is some misunderstanding of Fiber.Here is our benchmark 2 years ago, which shows Fiber has much much much better performance than the current model of Node.js. Here is the benchmark report https://github.com/fibjs/fibjs/blob/master/perf/http_server/performance-en.md |
2 years ago is a long time - performance just radically changed across the board in V8 with the new Turbofan JIT... |
Fibers are technically capable of better performance, being a lower-level concept than async/await, but I think the flexibility/interop advantages of async/await far outweighs any slight perf boost you might get from fibers. It's likely async/await could be optimized enough to effectively be fibers internally anyway. |
@ngot oof. Those benchmarks are against v0.10. You might wanna update this to compare against the latest |
The benchmark was 2 years ago, I'll run a benchmark recently and update the result. But before that I can say something I can conclude. In the previous benchmark, it shows fibjs is 14 times faster than nodejs when QPS is 100K. At that time, nodejs don't have "turbofan", neither the fibjs. Actually, now the benchmark node.js probably perform much slower than before, because the previous tests are based on simply callback mode(only libuv), now if we test with promise/async, it will be 100+ times slower than callback mode. Anyway, you can always run the benchmark on your own using any version of node to prove this. Like @Qard said, Fibers are technically capable of better performance and it will get much much faster with the correct optimizing. @benjamingr I'm confusing that you are comparing Fiber with bluebird. They are like apples and oranges. IMO, you should compare fiber with libuv. In Node.js, the real process of async/promise is: libuv + v8(async/promise), while in fibjs, the process is only fiber. Now the fiber is faster than libuv. When talking about the performance of fiber, it's not related to how fast async/promise is. |
Here is a very simple benchmark under the newest version of both Node.js & fibjs. benchmark.js const fs = require('fs');
const isFiber = typeof module === 'undefined';
const num = 100000;
if (isFiber) {
console.time('fiber');
for (let i = 0; i < num; i++) {
fs.readFile(__filename);
}
console.timeEnd('fiber');
} else {
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
(async () => {
console.time('async');
for (let i = 0; i < num; i++) {
await readFile(__filename);
}
console.timeEnd('async');
})();
} the result on my Macbook Pro 15 is: ➜ node -v
v8.4.0
➜ node benchmark.js
async: 5271.769ms
➜ fibjs -v
v0.11.0
➜ fibjs benchmark.js
fiber: 919.061ms Fiber is almost 6x faster than event+async at this condition. |
This is really cool -- to ask my next question: do you think it's possible to merge the two such that fibers are the underlying implementation structure for async/await, so we can preserve compatibility while using suck a fast implementation? I think the ecosystem bit is definitely worth considering. async/await have the benefit that we're able to do shenanigans in the background, even if it's only for, say, builtins. Compiling |
Actually, it is already implemented in fibjs for a long time. benchmark.js const fs = require('fs');
const sync = require('util').sync;
const num = 100000;
let readFile = filename => {
return new Promise((resolve, reject) => {
fs.readFile(filename, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
};
readFile = sync(readFile, true);
console.time('async');
for (let i = 0; i < num; i++) {
readFile(__filename);
}
console.timeEnd('async'); the result is: ➜ fibjs -v
v0.11.0
➜ fibjs benchmark.js
async: 7879.971ms Another one benchmark.js const fs = require('fs');
const num = 100000;
const readFile = filename => {
return new Promise((resolve, reject) => {
fs.readFile(filename, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
};
(async () => {
console.time('async');
for (let i = 0; i < num; i++) {
await readFile(__filename);
}
console.timeEnd('async');
})(); the result is: ➜ fibjs -v
v0.11.0
➜ fibjs benchmark.js
async: 3141.743ms The performance of these two ways is bad because the promise is very slow.If you don't give up async/promise, there is no possibility to get high performance. The reason why fibjs is so fast is that our implementation of fiber is faster than libuv's callback mode.Besides, we also don't need async/promise which is very very slow. |
It's not just about performance. Fibers allows for deep continuations a.k.a. true coroutines, something generator-based approach can never achieve. |
That's not a thing the JS language provides, though. Why should node provide it, as opposed to an actual language proposal? |
Actually, I want to be proven wrong here - and I want you to know you're being taken seriously here and your suggestions and feedback are welcome. Would you please:
If you have any questions in any of these stages please don't hesitate to ask and I promise to help. Then, once we have common ground with an experiment showing fibers are faster in a well known benchmark* we can discuss the performance implications with the V8 team and maybe experiment with fibers in core. As @ljharb said, the process would still require a lot of work after fibers are shown to be faster (if they are) and discussion about the many implications. Even if fibers are significantly faster it still doesn't mean we can integrate them. Let's not get too far ahead of ourselves though. * (so far they have been consistently shown them to be slower so far in our benchmarks - but I can see how integrating them into core gets a lot faster because - no closures - we got promises faster than callbacks at one point doing that). |
@benjamingr I'm afraid you still didn't get the point. There are lots of work to do if you want to bring fiber into the core because the whole libuv needs to be rewritten, so I'm not requesting Node.js to implement the fiber mode. I just want to point out that fiber is faster, here fiber is the lower-level concept than async/await. We've already implemented fiber in javascript in a project called fibjs, and according to the benchmark before, it shows the fiber is much faster than libuv. (14 times faster when qps is 100K) |
I ask that you moderate your comment above to use respectful language @ngot. If you would like to have meaningful and constructive discussion we're up for that. |
Sorry for that. My fault. My point is :
IMO, it is worth to think twice about this issue. |
The link between fibers and bluebird (or promises) is that both techniques allow writing synchronous looking asynchronous code. I realize the core underneath is different - that's why I asked that we have a well established benchmark as a point of discussion. In this case: doxbee which I linked to above. We are not dismissing any of your suggestions and Ayo (and Node.js too by the way) is willing to listen and discuss |
Great. |
I would like to point out that there are almost certainly large ecosystem dependencies in npm in regards to certain parts of libuv behavior. Changing that for existing APIs may have widespread negative impact. |
So if you want merge back to node in the future or compatibal with node 100%(fibjs is 90% compatibal with node),maybe you should not implement fiber in ayo,but if not,you could try it or contribute code to fibjs directly. |
Let me reiterate. Ayo (and again, Node.js too) are open to working together and experimenting with this sort of things. If there is anything we can do from our side that you would need in order to participate in the project and try to promote these ideas please let us know. I apologize if I sounded dismissive before and again - I would love to be proven wrong here. As @Fishrock123 said the barrier is going to be big because of possible ecosystem breakage - but I think that it's worth experimenting anyway. |
I agree it is worth experimenting with - unless I am radically misunderstanding what is involved however, it sounds like a native module would be a more ideal "proving grounds" for the work? That is, what is the blocker or burden than makes core a necessary host for this initially? |
Like fibjs did?
The text was updated successfully, but these errors were encountered: