Browse files

performance enhancements

Based on a yaws configuration consisting of an appmod registered on
"/" and simply returning {status, 204} with no response body, these
changes resulted in a 6.8% performance improvement on a modest older
Ubuntu 8.10 2.40GHz Core 2 Duo box with 2GB of RAM. The changes were
identified by analyzing fprof output, and performance was measured
using ab (ApacheBench) running on the same host as shown below:

ab -k -n 1000000 -c 1000 http://localhost:8200/

The access log was disabled and the listen backlog was set to 512, but
other than that the default configuration was used. Requests per
second went from ~14750 to ~15750. YMMV.
  • Loading branch information...
1 parent 8b5e74b commit 7c6fd31255ea9d0d183a333ad6712451f83d47f5 @vinoski vinoski committed Jul 24, 2010
Showing with 43 additions and 21 deletions.
  1. +43 −21 src/yaws_server.erl
View
64 src/yaws_server.erl
@@ -583,22 +583,24 @@ gserv_loop(GS, Ready, Rnum, Last) ->
{_From, next, Accepted} when Ready == [] ->
close_accepted_if_max(GS,Accepted),
New = acceptor(GS),
- GS2 = inc_con(GS),
+ GS2 = GS#gs{connections=GS#gs.connections + 1},
gserv_loop(GS2#gs{sessions = GS2#gs.sessions + 1}, Ready, Rnum, New);
{_From, next, Accepted} ->
close_accepted_if_max(GS,Accepted),
[{_Then, R}|RS] = Ready,
R ! {self(), accept},
- GS2 = inc_con(GS),
+ GS2 = GS#gs{connections=GS#gs.connections + 1},
gserv_loop(GS2, RS, Rnum-1, R);
{_From, decrement} ->
- GS2 = dec_con(GS),
+ GS2 = GS#gs{connections=GS#gs.connections - 1},
gserv_loop(GS2, Ready, Rnum, Last);
{From, done_client, Int} ->
GS2 = if
- Int == 0 -> dec_con(GS#gs{sessions = GS#gs.sessions - 1});
- Int > 0 -> dec_con(GS#gs{sessions = GS#gs.sessions - 1,
- reqs = GS#gs.reqs + Int})
+ Int == 0 -> GS#gs{sessions = GS#gs.sessions - 1,
+ connections = GS#gs.connections - 1};
+ Int > 0 -> GS#gs{sessions = GS#gs.sessions - 1,
+ reqs = GS#gs.reqs + Int,
+ connections = GS#gs.connections - 1}
end,
if
Rnum == 8 ->
@@ -912,8 +914,9 @@ acceptor(GS) ->
[] ->
proc_lib:spawn_link(?MODULE, acceptor0, [GS, self()]);
Opts ->
- %% as we tightly controlled what is set in options, we can blindly add "link" to
- %% get a linked process as per default case and use the provided options.
+ %% as we tightly controlled what is set in options, we can
+ %% blindly add "link" to get a linked process as per default
+ %% case and use the provided options.
proc_lib:spawn_opt(?MODULE, acceptor0, [GS, self()], [link | Opts])
end.
acceptor0(GS, Top) ->
@@ -1222,11 +1225,32 @@ fix_abs_uri(Req, H) ->
end.
-%% case-insensitive compare servername and ignore any optional
-%% :Port postfix
-comp_sname(Hname, Sname) ->
- hd(string:tokens(yaws:to_lower(Hname), ":")) =:=
- hd(string:tokens(yaws:to_lower(Sname), ":")).
+%% Case-insensitive compare servername and ignore any optional :Port
+%% postfix. This is performance-sensitive code, so if you change it,
+%% measure it.
+comp_sname([], []) ->
+ true;
+comp_sname([$:|_], [$:|_]) ->
+ true;
+comp_sname([$:|_], []) ->
+ true;
+comp_sname([], [$:|_]) ->
+ true;
+comp_sname([$:|_], _) ->
+ false;
+comp_sname(_, [$:|_]) ->
+ false;
+comp_sname([], _) ->
+ false;
+comp_sname(_, []) ->
+ false;
+comp_sname([C1|T1], [C2|T2]) ->
+ case string:to_lower(C1) == string:to_lower(C2) of
+ true ->
+ comp_sname(T1, T2);
+ false ->
+ false
+ end.
pick_sconf(GC, H, Group) ->
case H#headers.host of
@@ -4503,12 +4527,16 @@ vdirpath(SC, ARG, RequestPath) ->
%% specified in conf file for the 'vdir' directive.
Result.
+close_accepted_if_max(GS,{ok, _Socket})
+ when (GS#gs.gconf)#gconf.max_connections == nolimit ->
+ ok;
close_accepted_if_max(GS,{ok, Socket}) ->
MaxCon = (GS#gs.gconf)#gconf.max_connections,
NumCon = GS#gs.connections,
- if (MaxCon == nolimit) or (NumCon < MaxCon) ->
+ if
+ NumCon < MaxCon ->
ok;
- true ->
+ true ->
S=case peername(Socket, GS#gs.ssl) of
{ok, {IP, Port}} ->
io_lib:format("~s:~w", [inet_parse:ntoa(IP), Port]);
@@ -4522,12 +4550,6 @@ close_accepted_if_max(GS,{ok, Socket}) ->
close_accepted_if_max(_,_) ->
ok.
-inc_con(GS) ->
- GS#gs{connections=GS#gs.connections + 1}.
-
-dec_con(GS) ->
- GS#gs{connections=GS#gs.connections - 1}.
-
code_change(_OldVsn, Data, _Extra) ->
{ok, Data}.

0 comments on commit 7c6fd31

Please sign in to comment.