boostorg / beast

HTTP and WebSocket built on Boost.Asio in C++11
http://www.boost.org/libs/beast
Boost Software License 1.0
4.37k stars 636 forks source link

Async websocket creates a large binary & object file #2013

Open amnuwan opened 4 years ago

amnuwan commented 4 years ago

Version of Boost 1.70 ( 1.73 too )

Steps necessary to reproduce the problem

Build sample async ssl websocket example

https://www.boost.org/doc/libs/1_70_0/libs/beast/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp

On Mac OS with clang, This will produce a release binary 6.3 MB. This is not due to OpenSSL. You will see that object file ( websocket_client_async_ssl.o ) is also 3.8 MB.

And following statement contributes to shocking 3.1 MB of it.

// Perform the websocket handshake ws_.asynchandshake(host, "/", beast::bind_front_handler( &session::on_handshake, shared_from_this()));

while sync version of same ( ws_.handshake ), contributes only 400 KB extra.

File size changes as below.

  1. Async ws-handshake - ( obj: 3.8 MB, exe: 6.3 MB )
  2. No ws-handshake - ( obj: 0.5 MB, exe: 2.9 MB )
  3. Sync ws-handshake - ( obj: 0.9 MB, exe: 3.2 MB )

SSL present in all of above case.

I checked some cases with latest boost version 1.73 also, no noticeable change in reduction. Probably it takes more.

madmongo1 commented 4 years ago

Debug build or release? If release build, did you strip debugging symbols?

On Sat, 11 Jul 2020 at 12:41, amnuwan notifications@github.com wrote:

Version of Boost 1.70 ( 1.73 too )

Steps necessary to reproduce the problem

Build sample async ssl websocket example

https://www.boost.org/doc/libs/1_70_0/libs/beast/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp

On Mac OS , clang

This will produce a release binary bigger than 2.5 MB. This is not due to OpenSSL. You will see that object file ( websocket_client_async_ssl.o ) is also around 2 MB.

And following statement contributes to around 1.6 MB of it.

// Perform the websocket handshake ws_.asynchandshake(host, "/", beast::bind_front_handler( &session::on_handshake, shared_from_this()));

Striping reduces the size little bit ( like 200 KB ).

However sync version is not this big. If you replace above statement with ws_.handshake size get smaller by around 1 MB. Making total object size around 1 MB.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/boostorg/beast/issues/2013, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHOZSIAXXAJAA7YC6KF623R3A6W7ANCNFSM4OXH3D6A .

--

amnuwan commented 4 years ago

Debug build or release? If release build, did you strip debugging symbols?

Release build.

Stripping ( compiling with option -S ) increases object file further : from 3.8 MB to 23 MB Anyway I'm not able to link after stripping.

No luck with striping for me but better if we can find the reason for this bloat specially in async mode.

Further with respect to striping, additional symbols can help to debug a crash I suppose, which could be the reason they are in a release build, right ?

djarek commented 4 years ago

@amnuwan That's the wrong flag, -S does the following:

Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified.

The flag for stripping is -s.

As for the bloat- it's most likely related to how the async functions of websocket stream cause multiple instantiations of the async algorithms of the underlying stream, because multiple buffer types are passed.

amnuwan commented 4 years ago

@djarek thanks, I'll check about the option, I know striping can reduce the size a little, but if it has a cost to crash error reporting, I don't preffer that.

single statement cause 3.1 MB size increase, making beast is a difficult option for a mobile or embeded library overall. I'm developing a communication library, can't sacrifice around 5 MB of size just for websocket connectivity.

@djarek Mentioned template instantiation, how many templates would it require increase the size to this level by a single line of code. If this is unavoidable, then something is not right with the design of asio/beast. It lead us to consider, beast as a heavy library to perform websocket connectivity.

djarek commented 4 years ago

Some things that may help:

stale[bot] commented 4 years ago

This issue has been open for a while with no activity, has it been resolved?

amnuwan commented 4 years ago

No. The issue remains. 1st message has details to reproduce.

On Sun, 16 Aug 2020 at 3:19 PM, stale[bot] notifications@github.com wrote:

This issue has been open for a while with no activity, has it been resolved?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/boostorg/beast/issues/2013#issuecomment-674490938, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCND2G7HLKEOCG73SUF5MDSA6CADANCNFSM4OXH3D6A .

--


A.M Nuwan Abeysinghe Mobile : +94 71 5800808 T.P : +94 11 2617273

madmongo1 commented 4 years ago

Ok, I’ve been off work for a few days. I’ll tackle this on Monday.

Thanks for your patience.

amnuwan commented 4 years ago

Any update on this ?

On Sun, Aug 16, 2020, 16:09 Richard Hodges notifications@github.com wrote:

Ok, I’ve been off work for a few days. I’ll tackle this on Monday.

Thanks for your patience.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/boostorg/beast/issues/2013#issuecomment-674495860, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCND2CNF3S5RGQQNMGIJLLSA6H37ANCNFSM4OXH3D6A .

madmongo1 commented 4 years ago

Yes, we've been in discussion on how we can reduce template type expansions for internal completion handlers with little impact on performance.

We have a plan, and work is under way.

amnuwan commented 4 years ago

Nice, so I will continue to use beast for mobile assuming size will be reduced in the recent future.

Below library generate a really small binary I was thinking use it if beast couldn't fix this.

https://machinezone.github.io/IXWebSocket/

Thanks !

madmongo1 commented 4 years ago

great. we're on it.

stale[bot] commented 4 years ago

This issue has been open for a while with no activity, has it been resolved?

stale[bot] commented 4 years ago

It looks like this issue has either been abandoned or resolved so I will go ahead and close it. Feel free to re-open this issue if you feel it needs attention, or open new issues as needed. Thanks!

amnuwan commented 4 years ago

Can this take some time to be resolved ? Like 2-4 months ?

madmongo1 commented 4 years ago

It can, depending on what else is distracting the maintainer :)

PRs are always welcome if you'd like to help move the process along.

stale[bot] commented 4 years ago

This issue has been open for a while with no activity, has it been resolved?

stale[bot] commented 3 years ago

It looks like this issue has either been abandoned or resolved so I will go ahead and close it. Feel free to re-open this issue if you feel it needs attention, or open new issues as needed. Thanks!

amnuwan commented 3 years ago

As a mitigation, following things helped

-fvisibility=hidden -Os -flto=full -Wl,--gc-sections,--as-needed Also striping

In my project, overall I was able to obtain .so file of size 3.1 MB ( Around 2 MB goes to beast ).

Object file correspond to beast connection with above line is still 4.3 MB. It's a small 350 lines class which has nothing else but beast websocket connection with SSL.

This problem is severe only when it comes to android mobile applications. It will be really helpful for others if we put some warning at main page. Like below,

Warning : Websocket code with SSL contributes to additional ~1-2 MB release binary size when compiled as ".so" library.

dfranusic commented 2 years ago

I am using Boost.Beast to implement a Websocket SSL server on a range of embedded devices. Although "losing" around two megabytes of free space is not a big issue, it would be great if the resulting binary (or object file) could be trimmed down a bit.

pfeatherstone commented 1 month ago

I've noticed massive binary sizes too. I'm also using Boost.Json for parsing/writing HTTP requests/response. A very simple HTTP + Websocket over SSL application with some JSON parsing results in a 7MB binary with everything statically linked. It's massive. I'm also putting this on an embedded device but i can get away with it. I've noticed this a lot with Boost libraries. The compile times and binary sizes are massive. Fantastic libraries but what is it about Boost and bloated bins.

ashtum commented 1 month ago

I've noticed massive binary sizes too. I'm also using Boost.Json for parsing/writing HTTP requests/response. A very simple HTTP + Websocket over SSL application with some JSON parsing results in a 7MB binary with everything statically linked. It's massive. I'm also putting this on an embedded device but i can get away with it. I've noticed this a lot with Boost libraries. The compile times and binary sizes are massive. Fantastic libraries but what is it about Boost and bloated bins.

Are you sure you're building in release mode? Based on what you've explained, a binary size of 1 to 2 MB is expected.

pfeatherstone commented 1 month ago

I'm building with -O3 -ffast-math -s. In debug mode, I get a binary of size 47MB. I've also got a CLI using Boost.program_options. I forgot to mention that. But how much is that adding?

ashtum commented 1 month ago

Unfortunately, there isn’t much you can do about it. Both Asio and Beast are heavily templated, and even small changes to message types result in the re-instantiation of containers and operations. If you have many message types, you might want to give http::message_generator a try, but I don't expect it to make a huge difference.

pfeatherstone commented 1 month ago

OK, I guess that's the nature of heavily templated libraries. There is no such thing as a zero-cost abstraction.

amnuwan commented 1 month ago

Something is wrong if the size increase is this big for a websocket implementation over existing asio socket layer. I understand the unavoidable size difference for TLS implementation but there is a significant increase on top of it.

Also make sure to try related “strip” commands post release build. Sometimes it reduces the size by like 60%.

On Mon, 14 Oct 2024 at 21:27, pfeatherstone @.***> wrote:

OK, I guess that's the nature of heavily templated libraries. There is no such thing as a zero-cost abstraction.

— Reply to this email directly, view it on GitHub https://github.com/boostorg/beast/issues/2013#issuecomment-2411275442, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCND2AUCTESUFSV6M7YI53Z3PBFTAVCNFSM6AAAAABP463PUSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJRGI3TKNBUGI . You are receiving this because you were mentioned.Message ID: @.***>