Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use mmap for large files #13

Closed
jyn514 opened this issue Mar 17, 2019 · 4 comments
Closed

Use mmap for large files #13

jyn514 opened this issue Mar 17, 2019 · 4 comments

Comments

@jyn514
Copy link
Owner

jyn514 commented Mar 17, 2019

See #10

@jyn514
Copy link
Owner Author

jyn514 commented Mar 17, 2019

This is probably not very useful: https://stackoverflow.com/questions/45972/mmap-vs-reading-blocks#6383253. Would need to check with perf.

@jyn514
Copy link
Owner Author

jyn514 commented Mar 17, 2019

What this could help with is avoid double copies: currently perf looks like this (run again ab -n 100 -c 10 localhost:8080/data where data is binary with size 22897320 bytes:

-   92.23%     0.00%  main     main                 [.] respond (inlined)                   ▒
   - respond (inlined)                                                                      ▒
      - 52.98% handle_request (inlined)                                                     ▒
         - 52.77% _ZL10handle_urlR12request_infoRKSt3mapINSt7__cxx1112basic_stringIcSt11char▒
            - 52.59% get_file (inlined)                                                     ▒
               + 43.60% _ZNSi4readEPcl                                                      ▒
               + 7.31% ?? (inlined)                                                         ▒
               + 1.61% get_mimetype (inlined)                                               ▒
      + 38.35% __libc_send (inlined)

Note how 80% of the time is for IO: 38% for sending to the socket and 44% for reading from the file. If we could pass a pointer to an mmaped file instead of copying it, I imagine we'd get about double the speed.

@jyn514
Copy link
Owner Author

jyn514 commented Mar 17, 2019

Tested this both ways; this has a speedup of 48%! Counting this as a resounding success.

With std::ifstream.read:

$ ab -n 1000 -c 100 localhost:8080/data
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        crappy_server/0.0.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /data
Document Length:        22897320 bytes

Concurrency Level:      100
Time taken for tests:   17.691 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      22897536000 bytes
HTML transferred:       22897320000 bytes
Requests per second:    56.53 [#/sec] (mean)
Time per request:       1769.084 [ms] (mean)
Time per request:       17.691 [ms] (mean, across all concurrent requests)
Transfer rate:          1263980.68 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   10  90.7      1    1019
Processing:   445 1744 357.0   1763    3326
Waiting:       10  178 364.6     25    1772
Total:        446 1753 381.1   1764    3456

Percentage of the requests served within a certain time (ms)
  50%   1764
  66%   1773
  75%   1780
  80%   1790
  90%   1903
  95%   2403
  98%   2992
  99%   3235
 100%   3456 (longest request)

With mmap:

This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        crappy_server/0.0.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /data
Document Length:        22897320 bytes

Concurrency Level:      100
Time taken for tests:   10.887 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      22897533000 bytes
HTML transferred:       22897320000 bytes
Requests per second:    91.86 [#/sec] (mean)
Time per request:       1088.663 [ms] (mean)
Time per request:       10.887 [ms] (mean, across all concurrent requests)
Transfer rate:          2053976.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   29 165.4      1    1021
Processing:   367 1046 114.0   1077    1287
Waiting:        0   18  62.9      1     526
Total:        368 1074 207.9   1078    2302

Percentage of the requests served within a certain time (ms)
  50%   1078
  66%   1082
  75%   1085
  80%   1094
  90%   1100
  95%   1105
  98%   2093
  99%   2100
 100%   2302 (longest request)

@jyn514
Copy link
Owner Author

jyn514 commented Mar 17, 2019

c647900

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant