-
-
Notifications
You must be signed in to change notification settings - Fork 412
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
Very poor performance in TechEmpower Mutliple Queries #651
Comments
If I'm reading this right, the multiple queries benchmark creates a connection pool of 500? I know that Go for instance, resizes the connection pool based on number of queries. In the past when I debugged this issue, drivers which resize the connection pool based on number of queries and concurrency seemed to do the best. |
I guess we must play the benchmark game, i.e. have unbounded resource pool. In real life, it's not a good idea, but to win the game we have to be db-bound? |
Well with only 402 requests per second d I'm convinced some tweaking like you would do in the real world is needed anyway. |
Turning off content-type negotiation would make it significantly better and fairer (probably |
Wondering if this could be related to nikita-volkov/hasql#47 as well. |
servant (and other haskell frameworks) are slow in all the techempower benchmarks and come below many php, js, python, ruby solutions |
Latest numbers are even more confusing for that test, for top contender |
I think we all agree that it would be nice to do well in those benchmarks, but it seems relatively low priority compared to recent/ongoing/future developments, which are about improving the life of existing and new users. Those benchmarks are pretty much about "technical marketing". If anyone's willing to put in the time, servant devs would definitely be around to help in the investigation. But actual servant (or more generally wai/warp) applications do perform well, which is why I'm calling the benchmarks "marketing". |
We can sponsor a small bounty if anyone wants to take a shot at this. http://www.vacationlabs.com/haskell-bounty-program/ |
@saurabhnanda That would be very generous of Vacation Labs, thanks! We'd definitely do our best to help anyone taking up that offer with the time we've got available. |
@alpmestan when you say "users" do you mean the developers that use servant or the end users? I don't know about the current developers who use vagrant but i don't think you can assume that new developers don't care about performance. When you say "servant performs well" it's not clear without some measurements. Actually that is what i like about the techempower benchmarks that it gives you 6 different metrics and what is even better is that you can compare to so many other frameworks. To me actual performance numbers is what it is about (not necessarily the ones from techempower), this is not marketing but impacting on how beefy your server needs to be to serve X amount of users. If you agree with me that performance is important, then we can argue about the techempower benchmarks specifically. I don't belief that these benchmarks are so many percentage points off that they would not reflect real world usage. The goal of the benchmarks is to measure as realistically as possible. Of course your app is dependent on business logic and other things too, but these things are also not part of the servant code base. And we can't do any optimization on code that we don't know about. It would be nice to acknowledge the impact the lower level code (the framework) has to the overall application (added business logic). |
@flip111 We have investigated those benchmarks significantly in the past (@jkarni in particular). They never really revealed any problem with servant. For instance, for the DB benchmarks, the performance is determined mostly by the performance of the database library. In some other benchmarks, what costs us is that we aways do content type negotiation because the benchmarks do so little that this matters. And of course many other implementations completely skip that, which violates the HTTP spec. Also, a lot of the performance is determined by But I'm not saying those benchmarks are completely useless. I'd be happy if someone worked on this. I'm just saying that we have put a decent amount of time into this before and, I believe, got everything we could out of that effort, at the time. Moroeover, a bunch of development and documentation tasks are waiting for us already, and we know for sure that we're going to address problems that people have if we handle those tasks. So this is only a matter of prioritising. Which is why I'm saying that I'd be happy to help if someone wants to pick this up. |
@flip111 I'm not a Servant contributor but I use and appreciate the project, and while agree with some of what you are saying (performance is important to measure and consider), I believe there are some things about Techempower that make it lower priority for the servant team, and I think that's a perfectly fine stance to take. I certainly can't speak for the team but perhaps some context will be useful here:
Now, with all that said, I think it would be a fine pursuit for a group of people interested in supporting and marketing Servant to try to build something to game the benchmarks or to optimize the existing the effort. I'd be interested in contributing to that project (if I had the time, of course...), but I have no qualms whatsoever with the Servant team themselves continuing to make progress on the project instead of focusing on Techempower and I appreciate their efforts in this regard. Lastly, perhaps it would be constructive to add some sort of performance-testing suite to Servant-server completely independent of Techempower? This may allay the concerns of people who are surprised to see its performance on Techempower, and in the future, it could always be pointed to for those looking for numbers or it could also be used to spot ineffeciencies that arise. For my own uses, for instance, Servant has always been perfectly performant enough for my needs. (I typically run load-testing on my projects using |
@alpmestan you say a lot of performance is depended on warp (and thus wai ?). I took a look at wai performance some time ago, but i was not able to draw a conclusion from the information i collected. It might be interesting to someone else though, it can be found here yesodweb/wai#663 |
@flip111 Mostly warp because it is the library that implements the actual HTTP server, i.e that turns wai Now, it would be useful to have benchmarks Warp seems to have a benchmark for its HTTP request parser, but not a more comprehensive benchmarking suite that would maybe use In summary:
|
- Pool size now matches the max concurrency of requests used by the benchmark. Many other framworks appear to do similar matching. - Idea inspired by: haskell-servant/servant#651 (comment) - This finally restores all performance regression caused by `114b1b8`. Additionally we now finally blow past the performance of master at `6250eb8`.
* Bump to latest stable compiler, stackage resolver and libs. - Removed upper bounds for libs since the stackage resolver already takes care of pinning versions for us. - Removed extra-deps from stack config since resolver now contains `hasql-pool`. - Addressed `hasql` incompatibilities arising from upgrades to latest version. - Addressed runtime issue caused by `servant` upgrade changes where invalid parameters are now an error instead of no value. Added a datatype to handle invalid type coercion to 1 as the benchmark rules expect. - Error responses now describe the cause for a 500 to help debug issues. * Add `--pedantic` flag to catch even more warnings. * Re-use a single session across statements to regain some lost performance from `114b1b8`. - Switch to `unit` decoder for `updateSingle` statement as it now fails when being used in a session with other statements. We really dont need/use the result and as such can safely move to returning `()`. * Bump pool size to workaround `libpq` locking. - Pool size now matches the max concurrency of requests used by the benchmark. Many other framworks appear to do similar matching. - Idea inspired by: haskell-servant/servant#651 (comment) - This finally restores all performance regression caused by `114b1b8`. Additionally we now finally blow past the performance of master at `6250eb8`.
@jkarni: Based on your comments: I'd like to try and create a version of the servant benchmark less content-type negotiation. From my dig into the source code, I believe the escape hatch to disable the negotiation is to use
|
using |
To elaborate a little more: if your servant app solely consists of a |
If anyone is interested in speeding up WAI, please comment on this yesodweb/wai#663 |
To give some context to what @naushadh is doing, we want to benchmark the overhead of content-type negotiation. I believe using Is it possible to keep routing, but disable content-type negotiation for the purpose of a synthetic benchmark? Also, what exactly does "content-type negotiation" mean? Is it what this combinator does...
If yes, then is it possible to have a build where the first matching route is used, while disregarding the content-type specified in the route? |
And, just to check if the "content-type" line-of-thought is still relevant -- @naushadh is servant better than yesod on your version of the benchmarks now? If not, then this is still relevant. |
Disregarding |
@phadej I understand where you're coming from. I'm not suggesting we actually remove content-type negotiation from servant. This is just an academic exercise to understand how much content-type negotiation costs in terms of performance. |
I would be surprised it costs measurably more then other things we do in routing (e.g. parsing capture fields); but I don't know. That can be benchmarked in isolation.
|
I recall having reason to think that in the benchmarks involving simple
requests (no DB etc) content-type negotiation was actually quite
significant.
In order to remove it but keep routing, you'd have to write a version of
reqbody and verb that doesn't do negotiation. On my phone now so it's a bit
hard to give more details, but if you look at the HasServer instance for
those, it should be obvious how to do it.
(Still feels like it's the benchmark that ought to change, but I guess
we'll never win that battle, and it's understandable that now it'd break
everything.)
Em seg, 25 de mar de 2019 13:08, Oleg Grenrus <[email protected]>
escreveu:
… I would be surprised it costs measurably more then other things we do in
routing (e.g. parsing capture fields); but I don't know.
That can be benchmarked in isolation.
-
http://hackage.haskell.org/package/http-media-0.7.1.3/docs/Network-HTTP-Media-Accept.html#t:Accept
- vs. e.g. parseUrlPiece for Day (or some other type with non trivial
format)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#651 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABlKmnCZuxQ1gzsdxtcAMiBBRfRcOlj5ks5vaLxEgaJpZM4LPZFc>
.
|
Yes if you want usual APIs but no content type negotiation, you want to define custom HasServer instances that bypass all the |
Most results from 2019-03-18;
@saurabhnanda: Servant is about as fast as Now snap is an interesting contender. |
Hi all, I hope that you feel this is an appropriate place. I feel like the multiple queries benchmark that TechEmpower does is one of the more useful benchmarks, and I surprisingly see dismal results for the hasql/servant combination:
I feel that Servant/hasql should be on par with Go (4195 requests per second) but is only 10% of that at 402 requests per second. I'd like to be able to recommend servant for it's improved safety over Go for web api's but cannot with performance so much worse.
In the past I tried using Servant for some of my freelance clients and had to use a different tech stack when the result was too slow.
** I do acknowledge the problem seems to be concurrency around database bindings**, however I think database binding problems are a Servant problem if broader adoption is a large goal. This could be something simpler such as not compiling that benchmark with
-threaded
, though unlikely I think.I'll be looking into this more in the coming weeks.
The text was updated successfully, but these errors were encountered: