Skip to content

fasthttp.ServeFile can be too slow in some cases. #931

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

Closed
mehdipourfar opened this issue Dec 25, 2020 · 11 comments
Closed

fasthttp.ServeFile can be too slow in some cases. #931

mehdipourfar opened this issue Dec 25, 2020 · 11 comments

Comments

@mehdipourfar
Copy link

I have created a repository to show this.
fs-is-slow

@erikdubbelboer
Copy link
Collaborator

Which version of Go are you using? Which OS are you running?

This is the exact result I'm getting with your repo:

> go-wrk -d 3 "http://localhost:8080/1"
Running 3s test @ http://localhost:8080/1
  10 goroutine(s) running concurrently
46456 requests in 2.898406971s, 2.18GB read
Requests/sec:		16028.11
Transfer/sec:		769.49MB
Avg Req Time:		623.903µs
Fastest Request:	119.603µs
Slowest Request:	4.931075ms
Number of Errors:	0

> go-wrk -d 3 "http://localhost:8080/2"
Running 3s test @ http://localhost:8080/2
  10 goroutine(s) running concurrently
48137 requests in 2.892374375s, 2.26GB read
Requests/sec:		16642.73
Transfer/sec:		800.08MB
Avg Req Time:		600.863µs
Fastest Request:	90.846µs
Slowest Request:	7.147757ms
Number of Errors:	0

And this when I change it to image2.jpg:

> go-wrk -d 3 "http://localhost:8080/1"
Running 3s test @ http://localhost:8080/1
  10 goroutine(s) running concurrently
31819 requests in 2.906335014s, 2.25GB read
Requests/sec:		10948.15
Transfer/sec:		792.56MB
Avg Req Time:		913.396µs
Fastest Request:	196.059µs
Slowest Request:	26.513095ms
Number of Errors:	0

> go-wrk -d 3 "http://localhost:8080/2"
Running 3s test @ http://localhost:8080/2
  10 goroutine(s) running concurrently
33182 requests in 2.880574403s, 2.35GB read
Requests/sec:		11519.23
Transfer/sec:		834.65MB
Avg Req Time:		868.113µs
Fastest Request:	143.941µs
Slowest Request:	9.733838ms
Number of Errors:	0

@mehdipourfar
Copy link
Author

Thank you for your time.
go version go1.15.4 linux/amd64
Ubuntu Desktop 20.04.1 LTS

I have also tested it on three other machines. On two of them it is as slow as my system but in one of them it is fast. That one is a Ubuntu Server 20.04. I've just copied my go binaries compiled on my personal pc to it and ran it.

Do you have any idea how can I help to debug it? Why pprof will not generate any cpu profiles on fasthttp requests?

@erikdubbelboer
Copy link
Collaborator

You can use https://pkg.go.dev/github.com/valyala/fasthttp/pprofhandler for pprof. I have tried this myself but couldn't get anything useful out of it.

I have an Ubuntu 18.04.4 server with go1.15.3 which has the same issue.

This is the simplest code to reproduce it within main.go:

type bigFileReader struct {
        f *os.File
}

func (r *bigFileReader) WriteTo(w io.Writer) (int64, error) {
        if rf, ok := w.(io.ReaderFrom); ok {
                return rf.ReadFrom(r.f)
        }
        panic("never reached")
}

func (r *bigFileReader) Read(p []byte) (int, error) {
        return r.f.Read(p)
}

func (r *bigFileReader) Close() error {
        return r.f.Close()
}

func serveWithReadingFile(ctx *fasthttp.RequestCtx) {
        s, err := os.Stat(image_path)
        if err != nil {
                panic(err)
        }
        f, err := os.Open(image_path)
        if err != nil {
                panic(err)
        }
        ctx.SetBodyStream(&bigFileReader{
                f: f,
        }, int(s.Size()))
}

This is slow for me. But if I comment out the WriteTo function it becomes fast. The existence of the WriteTo function makes fasthttp use https://golang.org/pkg/net/#TCPConn.ReadFrom which seems to be super slow on some systems. I'm wondering it this is a performance issue with this function in Go or if there's some underlying OS issue.

I didn't have more time to look into this but it might be related to golang/go#41513 or golang/go#30377

@erikdubbelboer
Copy link
Collaborator

I have looked a bit more into the issue and the real issue seems to be this Flush call:

fasthttp/http.go

Lines 1743 to 1745 in 70e00dc

if err := w.Flush(); err != nil {
return err
}

I guess it causes 2 extra round trips. The flush is required to have an empty send buffer to trigger sendfile.

I think we should look into changing the threshold for which we try to trigger sendfile usage. For bigger files it is faster but for smaller files the extra roundtrip causes too big an overhead.

@Compiler-Error
Copy link

FYI, image details..

user@host:fs-is-slow$ ls -alt image*
-rw-rw-r-- 1 user user 50235 Jan 21 03:17 image1.jpg
-rw-rw-r-- 1 user user 75803 Jan 21 03:17 image2.jpg

user@host:fs-is-slow$ file image2.jpg
image2.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, progressive, precision 8, 599x600, components 3

user@host:fs-is-slow$ file image1.jpg
image1.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=6, xresolution=86, yresolution=94, resolutionunit=2, software=GIMP 2.10.18, datetime=2020:11:10 19:28:53], progressive, precision 8, 500x500, components 3

@erikdubbelboer
Copy link
Collaborator

I have created a program to benchmark sendfile with net/http.

Here are the results for several OSes all on a 16 core VMs:

Ubuntu 20.04
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:     706.60 vs   20427.90 diff   -2791.01%
     2.0kb:     716.80 vs   21222.10 diff   -2860.67%
     3.0kb:     702.80 vs   21430.70 diff   -2949.33%
     4.0kb:     729.60 vs   20412.00 diff   -2697.70%
     5.0kb:     715.10 vs   20364.10 diff   -2747.73%
     6.0kb:     725.50 vs   20472.50 diff   -2721.85%
     7.0kb:     716.80 vs   20137.60 diff   -2709.38%
     8.0kb:     726.40 vs   20335.70 diff   -2699.52%
     9.0kb:     729.60 vs   20329.50 diff   -2686.39%
    10.0kb:     719.70 vs   20018.20 diff   -2681.46%
    20.0kb:     715.20 vs   19806.10 diff   -2669.31%
    30.0kb:     717.50 vs   19337.00 diff   -2595.05%
    40.0kb:     722.30 vs   18998.80 diff   -2530.32%
    50.0kb:     718.50 vs   18153.00 diff   -2426.51%
    60.0kb:     710.00 vs   18336.30 diff   -2482.58%
    66.0kb:     713.20 vs   17793.70 diff   -2394.91%
    66.0kb:   44677.30 vs   17552.00 diff      60.71%
    70.0kb:   43157.90 vs   17540.80 diff      59.36%
    80.0kb:   42678.50 vs   16633.60 diff      61.03%
    90.0kb:   43080.00 vs   17348.00 diff      59.73%
   100.0kb:   17737.20 vs   16612.30 diff       6.34%
   200.0kb:    3894.60 vs   14035.10 diff    -260.37%
   300.0kb:    2343.60 vs   12395.80 diff    -428.92%
   400.0kb:    2779.30 vs   11168.40 diff    -301.84%
   500.0kb:    1833.50 vs   10121.80 diff    -452.05%
   600.0kb:    2215.50 vs    9272.90 diff    -318.55%
   700.0kb:    1661.70 vs    8337.10 diff    -401.72%
   800.0kb:    1846.80 vs    7572.50 diff    -310.03%
   900.0kb:    1657.80 vs    7347.50 diff    -343.21%
     1.0mb:    1753.40 vs    6943.90 diff    -296.02%
     1.1mb:    1414.30 vs    6497.10 diff    -359.39%
     1.2mb:    1606.20 vs    6094.20 diff    -279.42%
     1.5mb:    1332.50 vs    5383.30 diff    -304.00%
     2.0mb:    1386.80 vs    4392.60 diff    -216.74%
     2.5mb:    1662.10 vs    3744.00 diff    -125.26%
     3.0mb:    1272.90 vs    3235.80 diff    -154.21%
   100.0mb:     257.80 vs     153.30 diff      40.54%
   200.0mb:     129.50 vs      77.10 diff      40.46%
   300.0mb:      86.70 vs      51.90 diff      40.14%
   400.0mb:      65.30 vs      39.20 diff      39.97%
   500.0mb:      52.70 vs      31.70 diff      39.85%
   600.0mb:      44.00 vs      26.90 diff      38.86%
   700.0mb:      38.10 vs      22.90 diff      39.90%
   800.0mb:      33.70 vs      20.50 diff      39.17%
   900.0mb:      30.10 vs      18.80 diff      37.54%
     1.0gb:      27.10 vs      16.10 diff      40.59%
Debian 10
     size:   sendfile vs        r/w      sendfile faster
     1.0kb:     201.80 vs   20966.30 diff  -10289.64%
     2.0kb:     201.70 vs   21670.70 diff  -10644.03%
     3.0kb:     201.80 vs   21660.60 diff  -10633.70%
     4.0kb:     208.00 vs   20871.90 diff   -9934.57%
     5.0kb:     208.00 vs   21122.40 diff  -10055.00%
     6.0kb:     317.90 vs   20551.70 diff   -6364.83%
     7.0kb:     208.00 vs   20482.60 diff   -9747.40%
     8.0kb:     208.00 vs   19182.00 diff   -9122.12%
     9.0kb:     208.00 vs   20252.30 diff   -9636.68%
    10.0kb:     208.00 vs   20057.40 diff   -9542.98%
    20.0kb:     208.00 vs   19366.20 diff   -9210.67%
    30.0kb:     208.00 vs   19300.80 diff   -9179.23%
    40.0kb:     206.20 vs   18349.20 diff   -8798.74%
    50.0kb:     208.00 vs   17927.90 diff   -8519.18%
    60.0kb:     207.10 vs   16962.30 diff   -8090.39%
    66.0kb:     206.70 vs   17446.60 diff   -8340.54%
    66.0kb:   49166.10 vs   17233.00 diff      64.95%
    70.0kb:   47402.80 vs   17020.20 diff      64.09%
    80.0kb:   45941.10 vs   16996.30 diff      63.00%
    90.0kb:   13578.30 vs   16769.40 diff     -23.50%
   100.0kb:    9143.20 vs   14763.30 diff     -61.47%
   200.0kb:    7409.70 vs   13496.30 diff     -82.14%
   300.0kb:    8566.60 vs   11609.40 diff     -35.52%
   400.0kb:    9131.60 vs   10333.40 diff     -13.16%
   500.0kb:    8884.00 vs    8548.70 diff       3.77%
   600.0kb:   10724.40 vs    8382.90 diff      21.83%
   700.0kb:    7439.70 vs    7432.80 diff       0.09%
   800.0kb:    8889.10 vs    6632.10 diff      25.39%
   900.0kb:    8299.80 vs    6481.90 diff      21.90%
     1.0mb:    8757.70 vs    6088.40 diff      30.48%
     1.1mb:    7156.50 vs    5664.00 diff      20.86%
     1.2mb:    7668.40 vs    5404.60 diff      29.52%
     1.5mb:    5676.80 vs    4756.50 diff      16.21%
     2.0mb:    5180.20 vs    3838.40 diff      25.90%
     2.5mb:    5237.20 vs    3252.20 diff      37.90%
     3.0mb:    4385.60 vs    2845.50 diff      35.12%
   100.0mb:     234.10 vs     143.40 diff      38.74%
   200.0mb:     119.30 vs      73.10 diff      38.73%
   300.0mb:      80.80 vs      49.80 diff      38.37%
   400.0mb:      60.50 vs      37.70 diff      37.69%
   500.0mb:      47.20 vs      29.50 diff      37.50%
   600.0mb:      41.10 vs      25.70 diff      37.47%
   700.0mb:      35.30 vs      22.20 diff      37.11%
   800.0mb:      31.10 vs      19.40 diff      37.62%
   900.0mb:      27.90 vs      17.50 diff      37.28%
     1.0gb:      25.30 vs      16.00 diff      36.76%
Centos 8
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:     764.90 vs   20628.20 diff   -2596.85%
     2.0kb:     764.80 vs   18279.40 diff   -2290.09%
     3.0kb:     764.80 vs   20545.30 diff   -2586.36%
     4.0kb:     778.00 vs   18653.80 diff   -2297.66%
     5.0kb:     777.90 vs   18570.10 diff   -2287.21%
     6.0kb:     777.60 vs   18715.50 diff   -2306.83%
     7.0kb:     778.10 vs   18306.40 diff   -2252.71%
     8.0kb:     777.70 vs   18290.90 diff   -2251.92%
     9.0kb:     777.00 vs   18270.80 diff   -2251.45%
    10.0kb:     778.00 vs   18796.20 diff   -2315.96%
    20.0kb:     777.80 vs   17977.70 diff   -2211.35%
    30.0kb:     777.60 vs   17915.40 diff   -2203.94%
    40.0kb:     774.20 vs   16693.60 diff   -2056.24%
    50.0kb:     775.50 vs   16459.60 diff   -2022.45%
    60.0kb:     775.90 vs   16354.20 diff   -2007.77%
    66.0kb:     775.10 vs   15420.60 diff   -1889.50%
    66.0kb:   45815.40 vs   15569.60 diff      66.02%
    70.0kb:   43780.20 vs   15241.20 diff      65.19%
    80.0kb:   42914.80 vs   15287.80 diff      64.38%
    90.0kb:   42403.80 vs   15031.60 diff      64.55%
   100.0kb:   41484.70 vs   14082.20 diff      66.05%
   200.0kb:    6354.20 vs   11793.60 diff     -85.60%
   300.0kb:    3735.10 vs   10085.10 diff    -170.01%
   400.0kb:    3841.30 vs    9022.90 diff    -134.89%
   500.0kb:    2897.80 vs    7702.20 diff    -165.79%
   600.0kb:    3122.80 vs    7402.00 diff    -137.03%
   700.0kb:    2737.40 vs    6899.40 diff    -152.04%
   800.0kb:    2967.30 vs    6377.70 diff    -114.93%
   900.0kb:    2412.20 vs    5992.60 diff    -148.43%
     1.0mb:    2724.20 vs    5630.20 diff    -106.67%
     1.1mb:    2232.40 vs    5330.50 diff    -138.78%
     1.2mb:    2677.00 vs    5040.30 diff     -88.28%
     1.5mb:    2146.70 vs    4345.20 diff    -102.41%
     2.0mb:    2445.70 vs    3532.60 diff     -44.44%
     2.5mb:    2465.20 vs    3072.20 diff     -24.62%
     3.0mb:    2017.90 vs    2672.20 diff     -32.42%
   100.0mb:     211.60 vs     130.50 diff      38.33%
   200.0mb:     105.20 vs      66.30 diff      36.98%
   300.0mb:      71.20 vs      44.70 diff      37.22%
   400.0mb:      53.60 vs      34.30 diff      36.01%
   500.0mb:      42.80 vs      27.70 diff      35.28%
   600.0mb:      36.70 vs      22.80 diff      37.87%
   700.0mb:      31.40 vs      19.60 diff      37.58%
   800.0mb:      27.90 vs      18.20 diff      34.77%
   900.0mb:      25.20 vs      16.00 diff      36.51%
     1.0gb:      22.10 vs      14.20 diff      35.75%

As you can see sendfile is somehow very very slow for small files. With each OS there is a big bump in performance between 65994 and 65995 bytes. This seems to be the boundary of a TCP packet (minus http header). Not sure why this affects sendfile so much.

I have also written something similar with fasthttp and how fasthttp.FS is implemented.

Here is the result:

Ubuntu 20.04
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:  102157.40 vs  100718.10 diff       1.41%
     2.0kb:  100855.60 vs  100145.40 diff       0.70%
     3.0kb:  102315.70 vs  100877.00 diff       1.41%
     4.0kb:   91688.10 vs   91279.40 diff       0.45%
     5.0kb:   91533.20 vs   91657.00 diff      -0.14%
     6.0kb:   92218.00 vs   91542.00 diff       0.73%
     7.0kb:   91510.60 vs   88140.40 diff       3.68%
     8.0kb:   92169.30 vs   91326.60 diff       0.91%
     9.0kb:     208.00 vs   30026.50 diff  -14335.82%
    10.0kb:     208.00 vs   30227.40 diff  -14432.40%
    20.0kb:     208.10 vs   27823.30 diff  -13270.16%
    30.0kb:     208.10 vs   29558.10 diff  -14103.80%
    40.0kb:     207.20 vs   27734.00 diff  -13285.14%
    50.0kb:     207.90 vs   27146.60 diff  -12957.53%
    60.0kb:     207.80 vs   26804.90 diff  -12799.37%
    66.0kb:   24400.10 vs   25842.80 diff      -5.91%
    66.0kb:   25818.70 vs   25834.50 diff      -0.06%
    70.0kb:   17558.20 vs   25866.10 diff     -47.32%
    80.0kb:    9746.00 vs   25937.90 diff    -166.14%
    90.0kb:    6035.00 vs   24295.10 diff    -302.57%
   100.0kb:    4669.40 vs   24210.80 diff    -418.50%
   200.0kb:   12654.30 vs   19986.90 diff     -57.95%
   300.0kb:    5805.80 vs   16814.10 diff    -189.61%
   400.0kb:   12378.20 vs   14671.90 diff     -18.53%
   500.0kb:    8753.00 vs   13010.70 diff     -48.64%
   600.0kb:   13208.40 vs   11797.80 diff      10.68%
   700.0kb:    9873.50 vs   10761.70 diff      -9.00%
   800.0kb:   12430.10 vs    9779.30 diff      21.33%
   900.0kb:    8735.60 vs    9081.70 diff      -3.96%
     1.0mb:   10430.80 vs    8398.00 diff      19.49%
     1.1mb:    7282.60 vs    7872.50 diff      -8.10%
     1.2mb:    9467.60 vs    7400.40 diff      21.83%
     1.5mb:    6826.30 vs    6301.20 diff       7.69%
     2.0mb:    6858.80 vs    5096.70 diff      25.69%
     2.5mb:    6242.80 vs    4280.40 diff      31.43%
     3.0mb:    5157.60 vs    3706.90 diff      28.13%
   100.0mb:     248.50 vs     151.30 diff      39.11%
   200.0mb:     124.60 vs      76.10 diff      38.92%
   300.0mb:      83.40 vs      51.90 diff      37.77%
   400.0mb:      63.10 vs      39.10 diff      38.03%
   500.0mb:      50.50 vs      31.60 diff      37.43%
   600.0mb:      42.30 vs      26.60 diff      37.12%
   700.0mb:      36.50 vs      22.80 diff      37.53%
   800.0mb:      31.90 vs      20.20 diff      36.68%
   900.0mb:      28.80 vs      18.30 diff      36.46%
     1.0gb:      25.60 vs      16.00 diff      37.50%

For files below 8kb fasthttp doesn't flush the headers which prevents sendfile from being used. That's why its still fast for small files.

Around 1MB sendfile seems to be similar and with bigger files faster. So I would suggest increasing maxSmallFileSize to 1MB so we don't trigger sendfile below that size.

@mehdipourfar (and anyone else) can you please test my benchmarks (preferable both the fasthttp and net/http ones) on your machines and share the results here so we can compare different machines and OSes?

I want to use this research to also improve net/http to not use sendfile for too small files (here).

You can share the collapsed data like I did this way:

<details><summary>Ubuntu 20.04</summary>
<pre>
... data here...
</pre>
</details>

@mehdipourfar
Copy link
Author

mehdipourfar commented Feb 2, 2021

Here is the result of first test on my laptop with 4 cores and 16gb ram:

Ubuntu 20.04
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:     201.70 vs   28873.10 diff  -14214.87%
     2.0kb:     201.60 vs   25359.30 diff  -12479.02%
     3.0kb:     201.60 vs   27139.20 diff  -13361.90%
     4.0kb:     208.00 vs   22503.60 diff  -10719.04%
     5.0kb:     208.00 vs   21087.10 diff  -10038.03%
     6.0kb:     208.00 vs   23361.70 diff  -11131.59%
     7.0kb:     208.00 vs   21421.70 diff  -10198.89%
     8.0kb:     208.00 vs   22687.60 diff  -10807.50%
     9.0kb:     208.00 vs   22792.20 diff  -10857.79%
    10.0kb:     208.00 vs   23029.40 diff  -10971.83%
    20.0kb:     208.00 vs   21708.00 diff  -10336.54%
    30.0kb:     208.00 vs   19744.20 diff   -9392.40%
    40.0kb:     206.60 vs   18807.90 diff   -9003.53%
    50.0kb:     207.60 vs   17233.20 diff   -8201.16%
    60.0kb:     207.80 vs   17406.30 diff   -8276.47%
    66.0kb:     207.60 vs   16660.20 diff   -7925.14%
    66.0kb:   24920.20 vs   16635.70 diff      33.24%
    70.0kb:   22243.40 vs   15635.30 diff      29.71%
    80.0kb:   21614.10 vs   15023.90 diff      30.49%
    90.0kb:   21686.40 vs   14596.90 diff      32.69%
   100.0kb:   20765.80 vs   13763.50 diff      33.72%
   200.0kb:   16100.60 vs    9952.40 diff      38.19%
   300.0kb:   13088.80 vs    7651.70 diff      41.54%
   400.0kb:   11112.10 vs    6365.70 diff      42.71%
   500.0kb:    9550.60 vs    5385.80 diff      43.61%
   600.0kb:    7871.00 vs    4683.30 diff      40.50%
   700.0kb:    7375.90 vs    4102.30 diff      44.38%
   800.0kb:    6549.90 vs    3450.60 diff      47.32%
   900.0kb:    5842.20 vs    3293.20 diff      43.63%
     1.0mb:    5354.20 vs    2878.20 diff      46.24%
     1.1mb:    5317.00 vs    2715.30 diff      48.93%
     1.2mb:    4716.50 vs    2576.70 diff      45.37%
     1.5mb:    3906.00 vs    2056.10 diff      47.36%
     2.0mb:    3150.60 vs    1593.30 diff      49.43%
     2.5mb:    2438.20 vs    1305.90 diff      46.44%
     3.0mb:    2085.90 vs    1060.10 diff      49.18%
   100.0mb:      61.30 vs      36.60 diff      40.29%
   200.0mb:      32.10 vs      19.20 diff      40.19%
   300.0mb:      22.10 vs      12.80 diff      42.08%
   400.0mb:      16.30 vs       9.60 diff      41.10%
   500.0mb:      13.80 vs       9.60 diff      30.43%
   600.0mb:      12.80 vs       6.40 diff      50.00%
   700.0mb:       9.70 vs       6.40 diff      34.02%
   800.0mb:       9.60 vs       6.40 diff      33.33%
   900.0mb:       9.00 vs       6.40 diff      28.89%
        1.0gb:       6.40 vs       6.40 diff       0.00%

@mehdipourfar
Copy link
Author

And here is the results of the second test, again on my laptop.

Ubuntu 20.04 (fasthttp test)
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:   38730.00 vs   27537.20 diff      28.90%
     2.0kb:   34115.40 vs   40646.70 diff     -19.14%
     3.0kb:   38447.20 vs   37626.60 diff       2.13%
     4.0kb:   31612.70 vs   28817.00 diff       8.84%
     5.0kb:   30252.60 vs   29768.90 diff       1.60%
     6.0kb:   28384.00 vs   30855.30 diff      -8.71%
     7.0kb:   31220.70 vs   30460.40 diff       2.44%
     8.0kb:   29656.10 vs   27386.60 diff       7.65%
     9.0kb:     209.70 vs   15827.70 diff   -7447.78%
    10.0kb:     208.00 vs   19324.70 diff   -9190.72%
    20.0kb:     208.00 vs   17597.50 diff   -8360.34%
    30.0kb:     208.00 vs   17587.40 diff   -8355.48%
    40.0kb:     206.60 vs   13440.60 diff   -6405.61%
    50.0kb:     208.00 vs   14077.00 diff   -6667.79%
    60.0kb:     208.00 vs   11365.80 diff   -5364.33%
    66.0kb:   18790.60 vs   10890.70 diff      42.04%
    66.0kb:   20969.50 vs   13451.00 diff      35.85%
    70.0kb:   21698.90 vs   11246.70 diff      48.17%
    80.0kb:   18075.50 vs   12162.70 diff      32.71%
    90.0kb:   15109.10 vs    9559.70 diff      36.73%
   100.0kb:   19645.30 vs   10843.80 diff      44.80%
   200.0kb:   14048.00 vs    7265.30 diff      48.28%
   300.0kb:   10745.50 vs    5901.60 diff      45.08%
   400.0kb:    9267.10 vs    5828.80 diff      37.10%
   500.0kb:    9165.90 vs    5197.60 diff      43.29%
   600.0kb:    8828.50 vs    4509.20 diff      48.92%
   700.0kb:    5860.70 vs    3214.50 diff      45.15%
   800.0kb:    5274.10 vs    3534.10 diff      32.99%
   900.0kb:    5477.90 vs    2991.90 diff      45.38%
     1.0mb:    5231.90 vs    2313.30 diff      55.78%
     1.1mb:    4487.40 vs    2546.60 diff      43.25%
     1.2mb:    3466.70 vs    1867.10 diff      46.14%
     1.5mb:    3189.00 vs    1645.40 diff      48.40%
     2.0mb:    2613.60 vs    1284.60 diff      50.85%
     2.5mb:    2055.10 vs     980.60 diff      52.28%
     3.0mb:    1594.00 vs     842.90 diff      47.12%
   100.0mb:      55.50 vs      28.70 diff      48.29%
   200.0mb:      22.50 vs      14.50 diff      35.56%
   300.0mb:      19.20 vs       9.60 diff      50.00%
   400.0mb:      16.10 vs       9.60 diff      40.37%
   500.0mb:      12.70 vs       9.60 diff      24.41%
   600.0mb:       9.60 vs       6.40 diff      33.33%
   700.0mb:       9.60 vs       6.40 diff      33.33%
   800.0mb:       6.40 vs       6.40 diff       0.00%
   900.0mb:       6.40 vs       6.40 diff       0.00%
     1.0gb:       6.40 vs       3.20 diff      50.00%

@erikdubbelboer
Copy link
Collaborator

Windows WSL2 Ubuntu 20.04 LTS
      size:   sendfile vs        r/w      sendfile faster
     1.0kb:     609.20 vs   33916.80 diff   -5467.43%
     2.0kb:     608.20 vs   34450.80 diff   -5564.39%
     3.0kb:     608.60 vs   34763.70 diff   -5612.08%
     4.0kb:     621.20 vs   32598.60 diff   -5147.68%
     5.0kb:     624.00 vs   32422.00 diff   -5095.83%
     6.0kb:     623.60 vs   32367.60 diff   -5090.44%
     7.0kb:     623.90 vs   32219.60 diff   -5064.23%
     8.0kb:     627.20 vs   32264.00 diff   -5044.13%
     9.0kb:     627.80 vs   32055.00 diff   -5005.93%
    10.0kb:     626.70 vs   31948.30 diff   -4997.86%
    20.0kb:     627.00 vs   31254.50 diff   -4884.77%
    30.0kb:     626.70 vs   29488.60 diff   -4605.38%
    40.0kb:     622.80 vs   28533.10 diff   -4481.42%
    50.0kb:     621.80 vs   28075.10 diff   -4415.13%
    60.0kb:     623.40 vs   27610.60 diff   -4329.03%
    66.0kb:     616.40 vs   26526.60 diff   -4203.47%
    66.0kb:   57604.20 vs   26513.60 diff      53.97%
    70.0kb:   32767.80 vs   26187.20 diff      20.08%
    80.0kb:   53517.30 vs   25757.00 diff      51.87%
    90.0kb:   51916.60 vs   25380.00 diff      51.11%
   100.0kb:   50409.20 vs   24211.30 diff      51.97%
   200.0kb:    6139.00 vs   19525.10 diff    -218.05%
   300.0kb:    4600.30 vs   16430.80 diff    -257.17%
   400.0kb:    4437.60 vs   14219.40 diff    -220.43%
   500.0kb:    3467.50 vs   12369.80 diff    -256.74%
   600.0kb:    3954.60 vs   10962.40 diff    -177.21%
   700.0kb:    3155.80 vs    9857.20 diff    -212.35%
   800.0kb:    3411.60 vs    8888.70 diff    -160.54%
   900.0kb:    2822.10 vs    8066.90 diff    -185.85%
     1.0mb:    3167.40 vs    7374.50 diff    -132.83%
     1.1mb:    2570.30 vs    6830.20 diff    -165.74%
     1.2mb:    3043.60 vs    6313.90 diff    -107.45%
     1.5mb:    2477.10 vs    5161.70 diff    -108.38%
     2.0mb:    2384.60 vs    3935.60 diff     -65.04%
     2.5mb:    2761.90 vs    3182.10 diff     -15.21%
     3.0mb:    2441.40 vs    2659.50 diff      -8.93%
   100.0mb:     166.90 vs      82.70 diff      50.45%
   200.0mb:      82.80 vs      41.60 diff      49.76%
   300.0mb:      55.80 vs      28.70 diff      48.57%
   400.0mb:      41.90 vs      22.00 diff      47.49%
   500.0mb:      34.80 vs      17.40 diff      50.00%
   600.0mb:      28.80 vs      15.50 diff      46.18%
   700.0mb:      25.40 vs      12.90 diff      49.21%
   800.0mb:      22.40 vs      12.40 diff      44.64%
   900.0mb:      19.20 vs       9.60 diff      50.00%
     1.0gb:      18.70 vs       9.60 diff      48.66%

@erikdubbelboer
Copy link
Collaborator

I did some more research, it doesn't have to do with the file size it seems. Instead it has to do with keep-alive connections. The first sendfile on a new connection is always fast while followup sendfile calls on the same connection are always very slow. I made a Go issue about it: golang/go#45256

@erikdubbelboer
Copy link
Collaborator

As discovered in the Go issue, this behavior only happens with both receiver and sender are sockets on the same machine. I think it is up to Go to fix this, not fasthttp.

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

3 participants