I've skimmed through Taskflow, and from what I understand, its main focus is on graph parallelism, allowing users to express computations as a graph.
I haven't done extensive benchmarking against 3rd-party libraries yet, which others have also mentioned. I'll definitely do more performance testing in the future to better assess and optimize performance.
Regarding modern features, for example, the return value from the executor in TaskFlow is a custom tf::Future derived from std::future. This means if you want to check for the result, you need to use a try-catch block with the get() method on the future.
Personally, I prefer using std::expected for value/exception handling. It allows checking for errors with a simple if statement, and if you don't want to handle the exception, you can just return an error value from the coroutine.
As for "monadic-chaining," TaskFlow can achieve the same thing with its easy graph construction, you can set up a graph and execute it, which is comparable to and_then chaining in my library.
Another point is related to performance and ease of use. In a simple example like Fibonacci, TaskFlow requires using subflows, which I feel is less "ergonomic".
Overall, for simple task parallelism, if you don't need the graph expressiveness of TaskFlow, I believe my library is a more "ergonomic" choice (though I may be biased here). I also find value handling simpler in my library with std::expected. That said, TaskFlow is a much larger library with more features like GPU integration.
I've skimmed through Taskflow, and from what I understand, its main focus is on graph parallelism, allowing users to express computations as a graph.
I haven't done extensive benchmarking against 3rd-party libraries yet, which others have also mentioned. I'll definitely do more performance testing in the future to better assess and optimize performance.