10. Let me tell
why I had to write
a fast HTTP parser.
11.
12. Wookie is slower than Node.js
• Wookie is 2 times slower than Node.js
• Profiling result was saying
“WOOKIE:READ-DATA” was pretty slow.
• It was only calling “http-parse”.
• “http-parse” which is an HTTP parser
Wookie is using.
14. Wookie is slower than Node.js
• Node.js’s HTTP parse is “http-parser”.
• Written in C.
• General version of Nginx’s HTTP parser.
• Is it possible to beat it with Common Lisp?
20. HTTP request look like…
GET /media HTTP/1.1↵
Host: somewrite.jp↵
Connection: keep-alive↵
Accept: */*↵
↵
First Line
Headers
Body (empty, in this case)
21. HTTP request look like…
GET /media HTTP/1.1↵
Host: somewrite.jp↵
Connection: keep-alive↵
Accept: */*↵
↵ CR + LF
CRLF * 2 at the end of headers
30. http-parser (used in Node.js)
• https://github.com/joyent/http-parser
• Written in C
• Ported from Nginx’s HTTP parser
• Written as Node.js’s HTTP parser
• Stateful
31. http-parser (used in Node.js)
for (p=data; p != data + len; p++) {
…
switch (parser->state) {
case s_dead:
…
case s_start_req_or_res:
…
case s_res_or_resp_H:
…
}
}
32. http-parser (used in Node.js)
for (p=data; p != data + len; p++) {
…
switch (parser->state) {
Process char by char
case s_dead:
…
case s_start_req_or_res:
…
case s_res_or_resp_H:
…
}
}
Do something
for each state
34. PicoHTTPParser (used in H2O)
• https://github.com/h2o/picohttpparser
• Written in C
• Stateless
• Reparse when the data is incomplete
• Most HTTP request is small
36. fast-http is in the middle
• Not track state for every character
• Set state for every line
• It makes the program simple
• And easy to optimize
37. 5 important things
• Architecture
• Reducing memory allocation
• Choosing the right data types
• Benchmark & Profile
• Type declarations
38. Memory allocation is slow
• (in general)
• Make sure not to allocate memory during
processing
• cons, make-instance, make-array…
• subseq, append, copy-seq
39. 5 important things
• Architecture
• Reducing memory allocation
• Choosing the right data types
• Benchmark & Profile
• Type declarations
40. Data types
• Wrong data type makes your program slow.
• List or Vector
• Hash Table or Structure or Class
41. 5 important things
• Architecture
• Reducing memory allocation
• Choosing the right data types
• Benchmark & Profile
• Type declarations
42. Benchmark is quite important
• “Don’t guess, measure!”
• Check if your changes improve the
performance.
• Benchmarking also keeps your motivation.
44. 5 important things
• Architecture
• Reducing memory allocation
• Choosing the right data types
• Benchmark & Profile
• Type declarations
45. Type declaration
• Common Lisp has type declaration
(optional)
• (declare (type <type> <variable symbol>))
• It’s a hint for your Lisp compiler
• (declare (optimize (speed 3) (safety 0)))
• It’s your wish to your Lisp compiler
See also: Cより高速なCommon Lispコードを書く
46. (safety 0)
• (safety 0) means “don’t check the type &
array index in run-time”.
• Fast & unsafe (like C)
• Is fixnum enough?
• What do you do when someone passes a
bignum to the function?
47. (safety 0)
• fast-http has 2 layers
• Low-level API
• (speed 3) (safety 0)
• High-level API (safer)
• Check the variable type
• (speed 3) (safety 2)
49. Attitude
• Write carefully.
• It’s possible to beat C program
• (if the program is complicated enough)
• Don’t give up easily
• Safety is more important than speed