Based on my testing, when downloading 6 MB file from s3 from a fargate task it takes around 1.3 seconds. However, a 1.7 MB files takes 150 ms to finish. Assuming linear growth, 6MB should have taken at most around 600 ms. But this was not the case.
buff := aws.NewWriteAtBuffer([]byte{}))
getObjectInput := &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(uri),
}
, err = u.downloader.DownloadWithContext(ctx, buff, getObjectInput)
I spent a few hours trying to debug my service, and found that this set of code is not eats a lot of memory based on this. https://github.com/aws/aws-sdk-go/issues/3085
To correct this and use less memory, I changed my code to this.
getHeaderInput := &s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(uri),
}
res, _:= u.s3.HeadObject(getHeaderInput)
buff := aws.NewWriteAtBuffer(make([]byte, 0, *res.ContentLength))
getObjectInput := &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(uri),
}
, err = u.downloader.DownloadWithContext(ctx, buff, getObjectInput)
What I found is that the download time also decreased, and the overall duration of code is also shorter when downloading the 6MB file which is around 600ms as what it should be based on linear growth.
Buffer slice
[]byte{}or, equivalently,make([]byte, 0, 0)appends in amortized time.Buffer slice
make([]byte, 0, *res.ContentLength)appends in linear time.The Go Blog: Arrays, slices (and strings): The mechanics of 'append'