[erlang-questions] SSL performance

SeanD seand-erlang@REDACTED
Wed Feb 11 12:38:46 CET 2015


Hi,

We are experiencing a bottleneck in our application that has the option of
using SSL.  Conducting some generic tests, I am seeing that SSL can be upto
20,000 times slower when processing large amounts of data and was wondering
if anyone else has seen the same behaviour or can tell me that I'm doing
something really silly?

Transferring a 200MB binary between 2 nodes on the same machine using
gen_tcp is taking between 100 and 200 microseconds, whilst transferring the
same binary using ssl usually takes around 3 seconds!  I'm currently using
R16B01, but can happily move to a later version if this is required.

Is there any way to speed this up or any alternative SSL implementations
that call out to openssl natively that could be used instead?  Any insights
would be very welcome.

Thanks,
Sean

P.S.  The code I'm using is enclosed below:

-module(network_performance).

-export([client/0,ssl_client/0,server/1,ssl_server/1]).

client() ->
    SomeHostInNet = "localhost", % to make it runnable on one machine
    {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
        [binary, {packet, 0}, {active, once}]),
    Before = erlang:now(),
    ok = do_client_recv(Sock),
    After = erlang:now(),
    ok = gen_tcp:close(Sock),
    io:format("Time taken: ~p microsecs~n",[total_microsecs(After) -
total_microsecs(Before)]).

server(Data) ->
    {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, raw}, {active,
once},{reuseaddr,true}]),
    {ok, Sock} = gen_tcp:accept(LSock),
    gen_tcp:send(Sock, Data),
    gen_tcp:close(Sock).

ssl_client() ->
    SomeHostInNet = "localhost", % to make it runnable on one machine
    ssl:start(),
    {ok, Sock} = ssl:connect(SomeHostInNet, 5679,
        [binary, {packet, 0}, {active, once}]),
    ok = ssl:ssl_accept(Sock),
    Before = erlang:now(),
    ok = do_client_recv(Sock),
    After = erlang:now(),
    ok = ssl:close(Sock),
    io:format("Time taken: ~p microsecs~n",[total_microsecs(After) -
total_microsecs(Before)]).

ssl_server(Data) ->
    ssl:start(),
    {ok, LSock} = ssl:listen(5679, [binary, {packet, raw},
                                        {active,
once},{reuseaddr,true},{certfile,"test.pem"},{keyfile,"test.key"}]),
    {ok, Sock} = ssl:transport_accept(LSock),
    ok  = ssl:ssl_accept(Sock),
    ssl:send(Sock, Data),
    ssl:close(Sock).

total_microsecs({MegaSecs,Secs,MicroSecs}) ->
    (MegaSecs*1000000 + Secs)*1000000 + MicroSecs.

do_client_recv(Socket) ->
    receive
        {tcp, Socket, _Data} ->
            ok;
        {ssl, Socket, _Data} ->
            ok;
        {tcp_closed, Socket} ->
            io:format("Socket closed~n",[]);
        {tcp_error, Socket, Reason} ->
            io:format("Error: ~p~n",[Reason])
    after 20000 ->
            io:format("Receive timed out~n",[])
    end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150211/001fffce/attachment.htm>


More information about the erlang-questions mailing list