Skip to content
This repository has been archived by the owner on Nov 6, 2018. It is now read-only.

Reduce allocation in PhysicalFileProvider when used in StaticFiles #214

Merged
merged 3 commits into from
Jul 20, 2016

Conversation

pakrym
Copy link
Contributor

@pakrym pakrym commented Jul 19, 2016

By default we pass 64k buffer size but it causes significant overhead for small sized files.

Before:

Using 200byte file
http://i.imgur.com/DjMpeyl.png

After:

http://i.imgur.com/7EwGxZY.png

@Tratcher
@davidfowl // Note: Buffer size must be greater than zero, even if the file size is zero. why?

@@ -35,7 +35,7 @@ public Stream CreateReadStream()
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite,
1024 * 64,
Math.Min((int)Length, 1024 * 64),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FileStream defines the default buffer size to be 4k. Any idea why we picked a significantly larger number? Does it make sense to stick to the 4k value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fewer round trips we can do to the disk, the better.

Copy link

@campersau campersau Jul 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if Length is greater than int.MaxValue? I think it will overflow and would result in a value less than 0 which would also throw. https:/dotnet/corefx/blob/master/src/System.IO.FileSystem/src/System/IO/FileStream.cs#L85

long lng = (long)int.MaxValue + 1;
int i = Math.Min((int)lng, 1);
// i == -2147483648
long lng = long.MaxValue;
int i = Math.Min((int)lng, 1);
// i == -1

@pakrym pakrym changed the title Don't make FileStream allocate large buffers for small files Reduce allocation in PhysicalFileProvider when used in StaticFiles Jul 19, 2016
@Tratcher
Copy link
Member

:shipit:

@pakrym pakrym force-pushed the pakrym/stop-overallocation branch 2 times, most recently from c71c4d8 to c00e03d Compare July 19, 2016 21:12
@@ -29,13 +29,12 @@ public PhysicalFileInfo(FileInfo info)

public Stream CreateReadStream()
{
// Note: Buffer size must be greater than zero, even if the file size is zero.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this comment invalid? Because now Math.Min((int)Length, 1024 * 64) can return 0 which would result in an exception. Or can't Length be 0? https:/dotnet/corefx/blob/master/src/System.IO.FileSystem/src/System/IO/FileStream.cs#L85

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I verified 0 length file and it worked, but I re-tested and it didn't. Thank you for noticing.

@pakrym pakrym force-pushed the pakrym/stop-overallocation branch from c00e03d to 35796d2 Compare July 19, 2016 23:18
{
var fileName = Guid.NewGuid().ToString();
var filePath = Path.Combine(root.RootPath, fileName);
using (File.Create(filePath)) { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File.WriteAllBytes(filePath, new byte[0])? A bit cleaner than the single line dispose.

@pranavkm
Copy link
Contributor

:shipit:

1 similar comment
@rynowak
Copy link
Member

rynowak commented Jul 20, 2016

:shipit:

@davidfowl
Copy link
Member

Looks good

@davidfowl
Copy link
Member

Can you do some tests with large files to see what the before/after looks like?

@pakrym
Copy link
Contributor Author

pakrym commented Jul 20, 2016

@davidfowl why would it change for large files?

@@ -30,12 +30,13 @@ public PhysicalFileInfo(FileInfo info)
public Stream CreateReadStream()
{
// Note: Buffer size must be greater than zero, even if the file size is zero.
var bufferSize = (int)Math.Min(1024 * 64, Math.Max(1, Length));
Copy link
Member

@davidfowl davidfowl Jul 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make 1024 * 64 a constant MaxBufferSize

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

Successfully merging this pull request may close these issues.

8 participants