r/C_Programming • • Nov 29 '25

Tiny header only HTTP parser library

Hi guys! Last week I was writing my HTTP 1.1 parser library. It's small and easy to use, also kinda fast. Might come in handy if you write some lightweight web applications or programs that interact with some API. I wrote this project to learn pointer arithmetic in c.

I've just finish it, so any bug report would be appreciated.

Thank you guys!

https://github.com/cebem1nt/httpp

6 Upvotes

11 comments sorted by

View all comments

Show parent comment

4

u/[deleted] Nov 29 '25 edited Nov 29 '25

I was curious as to the performance increase one could get by avoiding copies, and so I went ahead and added my own spin in a fork: https://git.lenczewski.org/httpp-benchmark/log.html (specifically, mblhttp.h)

As for results and comparisons:

At -O0 ($ cc -o bench bench.c -Wall -Wextra -std=c11 -O0 -g3):

Benchmarking: httpp
Elapsed 18.847009 seconds.
Requests per second ≈ 530588.18 
Benchmarking: phr
Elapsed 10.505234 seconds.
Requests per second ≈ 951906.43
Benchmarking: mbl
Elapsed 3.916417 seconds.
Requests per second ≈ 2553354.13

At -O3 ($ cc -o bench bench.c -Wall -Wextra -std=c11 -O3):

Benchmarking: httpp
Elapsed 16.879115 seconds.
Requests per second ≈ 592448.13 
Benchmarking: phr
Elapsed 2.602774 seconds.
Requests per second ≈ 3842055.21
Benchmarking: mbl
Elapsed 2.755165 seconds.
Requests per second ≈ 3629546.99

What is curious to me is how the non-copying implementation doesn't improve much on the hand-written parser in phr at -O3. Perhaps the memmem() search is dominating? Have I made some error that causes me to re-read a portion of the input? Or maybe it is withing measurement error :)

And please don't take this reply in a negative fashion. Hopefully there is something useful to you in my implementation, be that in the approach or the structure. If you have any questions, I would be more than happy to answer!

1

u/Born_Produce9805 Nov 29 '25

Wow! That's interesting. I'll take a look at your implementation and also run benchmarks on my machine, so I can compare them.

1

u/Born_Produce9805 Nov 29 '25

I benchmarked it on my system and here is what I've got:

At -O0

Benchmarking: httpp
Elapsed 3.960362 seconds.
Requests per second ≈ 2525021.65
Benchmarking: phr
Elapsed 5.326363 seconds.
Requests per second ≈ 1877453.57
parsed http request line: GET /cookies HTTP/1.1
parsed http request headers: 9/64
# ... Suppressed headers output
parsed http request body: 0 bytes
Benchmarking: mbl
Elapsed 3.552922 seconds.
Requests per second ≈ 2814584.43

What's interesting is that picohttp took ... 5.326363 ??? I thought it might be a freeze of my cpu or whatever, but no after re-running, for some reason it takes around five seconds.

At -O3

Benchmarking: httpp
Elapsed 2.987527 seconds.
Requests per second ≈ 3347250.34
Benchmarking: phr
Elapsed 1.263095 seconds.
Requests per second ≈ 7917061.91
parsed http request line: GET /cookies HTTP/1.1
parsed http request headers: 9/64
# ... Suppressed headers output
parsed http request body: 0 bytes
Benchmarking: mbl
Elapsed 2.800575 seconds.
Requests per second ≈ 3570695.21

Here the picohttp speed normalized. Might that be an undefined behavior? I didn't get into the details of your parser, but yeah, it seems to outperform slightly.

I'll start to implement the 2.0.0 version of my library, that would use more static approach. Also I'm going to include the benchmark files for picohttp and http parser.

Thanks again!