В теории, конечный автомат — рулез. Он позволяет парсить поток даже при ленивом поступлении на вход данных по одному байту.
Например, в nginx запилена такая FSM (finite state machine), которая жрёт по 1 байту и идёт в длинный switch, где в зависимости от текущего состояния каким-то образом сжирает этот байт.
Но в реальной жизни в 99% случаев HTTP-запрос (пачка хидеров и завершающий двойной перевод строки) целиком приходит в одном пакете. То есть, при чтении из сокета в 99% случаев оказывается, что нам доступен целый запрос в буфере и FSM нам не нужен, мы можем запустить последовательность процедур, которые выцепят из этого буфера разные аспекты парсимого протокола.
Насколько большой оверхед даёт FSM в виде хождения в таблицу указателей на функции (это то, во что скомпилируется switch) на каждый байт?
Я понимаю, что FSM по-хорошему нужен. Кусок HTTP-запроса может прийти раньше второго куска. Малолетние хакеры могут захотеть посылать HTTP-запросы через nc по одной строчке и это выдержит nginx. Но в реальной жизни целый запрос обычно валится в виде одного пакета.