mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
OPTIM: channel: speed up co_getline()'s search of the end of line
Previously, co_getline() was essentially used for occasional parsing in peers's banner or Lua, so it could afford to read one character at a time. However now it's also used on the TCP log path, where it can consume up to 40% CPU as mentioned in GH issue #2731. Let's speed it up by using memchr() to look for the LF, and copying the data at once using memcpy(). Previously it would take 2.44s to consume 1 GB of log on a single thread of a Core i7-8650U, now it takes 1.56s (-36%).
This commit is contained in:
parent
7caf073faa
commit
11051ed9c7
@ -324,7 +324,7 @@ int co_getword(const struct channel *chn, char *str, int len, char sep)
|
|||||||
int co_getline(const struct channel *chn, char *str, int len)
|
int co_getline(const struct channel *chn, char *str, int len)
|
||||||
{
|
{
|
||||||
int ret, max;
|
int ret, max;
|
||||||
char *p;
|
size_t ofs;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
max = len;
|
max = len;
|
||||||
@ -336,20 +336,30 @@ int co_getline(const struct channel *chn, char *str, int len)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = co_head(chn);
|
|
||||||
|
|
||||||
if (max > co_data(chn)) {
|
if (max > co_data(chn)) {
|
||||||
max = co_data(chn);
|
max = co_data(chn);
|
||||||
str[max-1] = 0;
|
str[max-1] = 0;
|
||||||
}
|
}
|
||||||
while (max) {
|
|
||||||
*str++ = *p;
|
|
||||||
ret++;
|
|
||||||
max--;
|
|
||||||
|
|
||||||
if (*p == '\n')
|
ofs = 0;
|
||||||
|
|
||||||
|
while (max) {
|
||||||
|
size_t contig = b_contig_data(&chn->buf, ofs);
|
||||||
|
size_t len = MIN(max, contig);
|
||||||
|
const char *beg = b_peek(&chn->buf, ofs);
|
||||||
|
const char *lf = memchr(beg, '\n', len);
|
||||||
|
|
||||||
|
if (lf) /* take the LF with it before stopping */
|
||||||
|
len = lf + 1 - beg;
|
||||||
|
|
||||||
|
memcpy(str, beg, len);
|
||||||
|
ret += len;
|
||||||
|
str += len;
|
||||||
|
ofs += len;
|
||||||
|
max -= len;
|
||||||
|
|
||||||
|
if (lf)
|
||||||
break;
|
break;
|
||||||
p = b_next(&chn->buf, p);
|
|
||||||
}
|
}
|
||||||
if (ret > 0 && ret < len &&
|
if (ret > 0 && ret < len &&
|
||||||
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
||||||
|
Loading…
Reference in New Issue
Block a user