the-benchmarker / web-frameworks

Which is the fastest web framework?
MIT License
6.91k stars 641 forks source link

Add httpbeast #295

Closed dom96 closed 4 years ago

dom96 commented 5 years ago

https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Nim/httpbeast

waghanza commented 5 years ago

@dom96 does httpbeast support routing ?

dom96 commented 5 years ago

Depends how sophisticated the routing has to be. It is pretty barebones though.

waghanza commented 5 years ago

@dom96 the routes are pretty simple like described on #221

dom96 commented 5 years ago

Is doing some string handling acceptable?

if request.path.startsWith("/user/"):
  let id = request.path[6 .. ^1]
waghanza commented 5 years ago

@dom96 why not ^^^

Pour purpose is to compare performances, so no matter what impl

@tbrand what do you think about this ?

OvermindDL1 commented 5 years ago

why not ^^^

tbrand didn't accept that identical testing in the C++ version though, hence why it was converted to the slower regex path matcher. ;-)

dom96 commented 5 years ago

But why? :(

dom96 commented 5 years ago

https://github.com/tbrand/which_is_the_fastest/issues/181#issuecomment-380136460

That's a shame :/

waghanza commented 5 years ago

Sorry, mis-usage if irony here

For me it is totally inacceptable.

Why ? Because if routing feature as use on Real world applications.

jester and mofuw accepts dynamic routes, but wai (PR wating) is not -> we have to implement wai-routing to merge this PR

I think @tbrand will be on the same page (thats why I ping him)

What do you think about this ?

Sorry again for this

waghanza commented 5 years ago

For me parsing URL with a regexp is good (I have juste noticed that regexp un evhtp impl is too open).

What we want (for me) is routing, no matter what technic is used (regexp, or elle). However, this step SHOULD to be done as a dispatcher -> I mean handling http req to route to a spécifications code (not handling all urls in one function)

PS : @OvermindDL1 evhtp is enabled, but we have to restrict route

OvermindDL1 commented 5 years ago

PS : @OvermindDL1 evhtp is enabled, but we have to restrict route

It has quite a variety of routing interfaces, pick one? The regex one is the slowest though so if that is what you are wanting to compare...

waghanza commented 5 years ago

@OvermindDL1 could you list the routing interface ?

In the case of evhtp , routing has to be used only to check /user/%d on GET

waghanza commented 5 years ago

@dom96 could httpbeast routing be more restrictive ?

dom96 commented 5 years ago

More restrictive? What do you mean?

You can use regex for it too if you want, but I find that a little silly.

waghanza commented 5 years ago

I come from ruby world, and it does not blow my eyes when I read a route

get '/user/[\d]+, ....

But perhaps there is a smarter way to do (having one place where is defined callback in use and params), feel free to share ^^

OvermindDL1 commented 5 years ago

@OvermindDL1 could you list the routing interface ? In the case of evhtp , routing has to be used only to check /user/%d on GET

It has exact matching (exact string match, which most frameworks support), it has prefix matching (like how the elixir and many other frameworks primarily route on), it has regex matching (which frameworks like elixir do not support at all and you have to build it yourself), it has custom matching (supply your own matching and routing handler) that I know of off hand, and I think I'm missing one. In general the order supplied above is the efficiency that they run at (although the custom matching might be better or worse depending on what you do). Full full key processing and validation checking you use the regex matcher (which is what the evhtp benchmark is doing now).

get '/user/[\d]+, ....

That's essentially what evhtp is doing currently (although not \d I think as that wass not part of the readme requirements at the time, is it now?).

dom96 commented 5 years ago

I come from ruby world, and it does not blow my eyes when I read a route

My suggestion is surely not that much harder to read. The advantage is that it should be many times faster than resorting to Regex.

waghanza commented 5 years ago

@OvermindDL1 it's quite the case https://github.com/tbrand/which_is_the_fastest/blob/master/cpp/evhtp/main.cpp#L41 but there is not restriction How about prefix matching ? Could you show me a example

@dom96 does routing could be done something like one one line ?

waghanza commented 5 years ago

@OvermindDL1 do you have time to implement custom matching

if it's the fastest way to have routing, so why not having this in this project

OvermindDL1 commented 5 years ago

@OvermindDL1 it's quite the case /cpp/evhtp/main.cpp@master#L41 but there is not restriction

evhtp_set_regex_cb(htp, "^/user/([^/]+)", on_request_user_index, NULL); is precisely the restriction, it only matches that specific route path, equivalent to match "/user/:blah", CallbackModule, :callbackFunction in Elixir's Phoenix for example (although Elixir's would be faster since that is a prefix matcher).

So what restriction are you speaking of?

@OvermindDL1 do you have time to implement custom matching

That's essentially what I had originally but tbrand didn't like it and deleted ethtp entirely (wtf...) as it wasn't "built in"... >.>

waghanza commented 5 years ago

@OvermindDL1 I think a mis-understand match "/user/:blah" is more talkative to me, so it might be my confusion :stuck_out_tongue:

That's essentially what I had originally

Could you then give me an URL (or commit hash) ?

OvermindDL1 commented 5 years ago

This is where I did it with a combination prefix matcher and custom parser: https://github.com/tbrand/which_is_the_fastest/blob/24b8f660bd2cbe1bfa80da391c4ac3d9ed264dd7/cpp/evhtp/main.cpp

Specifically this line: https://github.com/tbrand/which_is_the_fastest/blob/24b8f660bd2cbe1bfa80da391c4ac3d9ed264dd7/cpp/evhtp/main.cpp#L24

const char *p = req->uri->path->full + 6; // 6 being the length of "/user/"

Being the line he objected to as it was not a built-in parser/matcher, where the regex does (it stores the matched segment into argument storage inefficiently and all just as he wanted).

EDIT: As a note, the above work is the exact same amount of work that a couple other frameworks (a rust one that I copied the handling of) did, so I don't know why it was not accepted nor why tbrand just removed it outright as it seemed exceedingly hypocritical (which was my whole issue with it...).

OvermindDL1 commented 5 years ago

@OvermindDL1 I think a mis-understand match "/user/:blah" is more talkative to me, so it might be my confusion stuck_out_tongue

What that does is the same as the regex, just a different syntax form of it that is more efficient as it does less work but also means the data is not in any expected form (have to validate it yourself and can't change the matcher based on the data type unlike how you can do with regex or a custom matcher).

dom96 commented 5 years ago

@dom96 does routing could be done something like one one line ?

I don't want to bloat httpbeast with routing. Plus the code I gave you is only two lines, it's really not that much.

waghanza commented 5 years ago

@OvermindDL1 personally, I prefer the https://github.com/tbrand/which_is_the_fastest/blob/24b8f660bd2cbe1bfa80da391c4ac3d9ed264dd7/cpp/evhtp/main.cpp impl

@dom96 convinced, please be my guest on PR

OvermindDL1 commented 5 years ago

@OvermindDL1 personally, I prefer the /cpp/evhtp/main.cpp@24b8f66 impl

As do I, but tbrand didn't and he deleted it all entirely outright, all in a single commit with other changes as well, thus preventing a rollback (still very wtfery there). Thus the regex implementation that lost ~10% of the performance overall based on quick tests at the time.

waghanza commented 5 years ago

@tbrand Is there any warnings about that ?

dom96 commented 5 years ago

I'll make a PR if @tbrand gives the OK :)

waghanza commented 5 years ago

@tbrand ok ?

@dom96 I'm OK for your PR ;-) (and jester fix if you have time)

tbrand commented 5 years ago

Can we say that the below code has a feature of routing?

if request.path.startsWith("/user/"):
  let id = request.path[6 .. ^1]

@dom96 You said

Extremely fast HTTP responses in Nim.

Yeah that's sound great! But the feature does not match to the concept of this repo. May be @waghanza will create other repos that will bench other features. I hope the httpbeast could be included in it.

waghanza commented 5 years ago

@tbrand For me httpbeast has routing feature (even if I personally found this not elegant comparing to ruby or crystal, but it's a matter of taste)

for me it's OK to include httpbeast in this repo

tbrand commented 5 years ago

@waghanza How?

For me httpbeast has routing feature

This way? https://github.com/the-benchmarker/web-frameworks/issues/295#issuecomment-428428206

waghanza commented 5 years ago

@tbrand Yep

I totally agree that this writing way COULD be strange for some devs, but this code match routes :

but not /users/1.

For me it is a routing feature in the way that a route is handled by a portion of code

waghanza commented 5 years ago

@tbrand also httpbeast is on tfb https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Nim probably it COULD be considered as a framework with the features we expect here

tbrand commented 5 years ago

Hmm I don't think so. If we accept it, it means every languages level implementation can be accepted. (e.g. Crystal, Ruby, ...) But if you wish, you could add it.

waghanza commented 5 years ago

you do not seems convinced ...

@OvermindDL1 what do you think ? (I do not want to take decisions unilaterally)

@dom96 for me an important point is : how we do not get out-of-sync ?

dom96 commented 5 years ago

every languages level implementation

What does that mean? Does it mean "every HTTP server implementation without a router?"

To be fair, your repo is called "web frameworks" so I can understand if you don't want HttpBeast in here. But IMO you should set the bar higher. Routing is relatively trivial.

for me an important point is : how we do not get out-of-sync ?

What do you mean "out-of-sync"?

waghanza commented 5 years ago

@dom96 I mean having outdated implementations of each frameworks

dom96 commented 5 years ago

It shouldn't be a big deal since you've pinned the versions.

waghanza commented 5 years ago

@dom96 If I can remind you, it will be better. I mean if codebase has to be updated, I prefer that its you (or an other nim dev) to take this task

OvermindDL1 commented 5 years ago

@OvermindDL1 what do you think ? (I do not want to take decisions unilaterally)

Seems fine to me to include it, what is being tested here isn't even the languages but rather how efficient their socket and string processing capabilities are considering how little time is spent in each language proper. If you really wanted to do testing of the frameworks then you'd need to test a lot more, concurrency, websockets, etc... etc... All that is being tested here is socket handling and some simple string processing.

waghanza commented 5 years ago

of course @OvermindDL1, a proper way to have a full-feature benchmark is to define a complete set of specs

I can handle work on implementations, but have no time to define a complete set of specs, if you are interested, feel free to write specs, I'll handle the coding part ;-)

@dom96 for me it's OK, you can open a PR

dom96 commented 5 years ago

Okay, may take me a bit. Busy with a house move right now :)

waghanza commented 5 years ago

No hurry 😊

waghanza commented 4 years ago

@dom96 ping ^^

dom96 commented 4 years ago

heh, I still have no time for this, sorry. Happy to review PRs if you want to implement httpbeast benchmarks yourself

waghanza commented 4 years ago

I'll try

waghanza commented 4 years ago

@dom96 any time to make a PR ?

waghanza commented 4 years ago

@dom96 The parsing way is not realy important, the most important here is to have one parsing reflecting the real-word usage

dom96 commented 4 years ago

Yeah, sorry, again, I'm happy to review any PRs. It should be fairly simple for you to implement this since you know exactly what you'd like out of the benchmark.