{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/23727","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/23727/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/23727/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/23727/events","html_url":"https://github.com/dotnet/corefx/pull/23727","id":254525864,"number":23727,"title":"Use ArrayPool in StreamWriter","user":{"login":"benaadams","id":1142958,"avatar_url":"https://avatars1.githubusercontent.com/u/1142958?v=4","gravatar_id":"","url":"https://api.github.com/users/benaadams","html_url":"https://github.com/benaadams","followers_url":"https://api.github.com/users/benaadams/followers","following_url":"https://api.github.com/users/benaadams/following{/other_user}","gists_url":"https://api.github.com/users/benaadams/gists{/gist_id}","starred_url":"https://api.github.com/users/benaadams/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benaadams/subscriptions","organizations_url":"https://api.github.com/users/benaadams/orgs","repos_url":"https://api.github.com/users/benaadams/repos","events_url":"https://api.github.com/users/benaadams/events{/privacy}","received_events_url":"https://api.github.com/users/benaadams/received_events","type":"User","site_admin":false},"labels":[{"id":197706871,"url":"https://api.github.com/repos/dotnet/corefx/labels/cla-already-signed","name":"cla-already-signed","color":"009800","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2017-09-01T03:26:58Z","updated_at":"2017-09-04T22:06:09Z","closed_at":null,"author_association":"COLLABORATOR","pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/23727","html_url":"https://github.com/dotnet/corefx/pull/23727","diff_url":"https://github.com/dotnet/corefx/pull/23727.diff","patch_url":"https://github.com/dotnet/corefx/pull/23727.patch"},"body":"Summary of main changes\r\n\r\nUse ArrayPool in StreamWriter\r\n* Rents **char** buffer on first `Write` or `WriteAsync` to backing buffer.\r\n* Rents **byte** buffer on first `Flush` or `FlushAsync` (can happen during `Write`s).\r\n* Returns **char** and **byte** buffer on `Stream` flush (doesn't always happen during `Flush` i.e. a mid `Write` flush. (Return once enforced using `Interlocked.Exchange`)\r\n\r\nFaster small Writes\r\n* Changed to using local vars for counts rather than class vars, for better register use\r\n\r\nCode depue\r\n* Merged `Write(char[], int, int)` and `Write(char[])` to `WriteInternal(char[], int, int)`\r\n* Merged `Write(string)`/`Writeline(string)` main functionality to `WriteInternal(string)`\r\n\r\nFor the blocking `Write(char[])`/`Write(string)`/`Flush`s specifically:\r\n* Below the `RentFromPoolThreshold` (64 bytes) it uses `stackalloc` rather than renting a **byte** buffer.\r\n* It buffers and writes chunks to the stream in `bufferSize` **char** arrays (as before)\r\n* If **char** buffer is empty and the remaining chars to write is above the `DontCopyOnWriteThreshold` (512 bytes); it encodes directly to the byte array rather than via the **char** buffer, in up to `bufferSize` chunks, leaving the remaining in the **char** array (i.e. less than `DontCopyOnWriteThreshold`). For large arrays and `string`s; when there is data in the buffer, this will occur second time in loop etc.\r\n* Above is achieved by additionally passing \"current\" char buffer to `Flush`; `string` and `char[]` types are merged by passing as `ReadOnlySpan<char>`.\r\n\r\nEffects\r\n* Small writes are faster <= 4 bytes\r\n* Medium writes a little slower (4 - 512 bytes) due to addition of array pool acquisition/release\r\n* Large writes faster as no extra copy prior to transform\r\n* Allocations from creating and using `StreamWriter` from 5432 bytes, to 264 bytes (Encoder is quite big)\r\n\r\nFurther enhancements that can be done\r\n\r\n* Use `DontCopyOnWriteThreshold` for `WriteAsync` also\r\n\r\nContributes to https://github.com/dotnet/corefx/issues/5598 /cc @stephentoub \r\nFixes https://github.com/dotnet/corefx/issues/8376 /cc @GSPP @ianhays \r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/327033332","html_url":"https://github.com/dotnet/corefx/pull/23727#issuecomment-327033332","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/23727","id":327033332,"user":{"login":"benaadams","id":1142958,"avatar_url":"https://avatars1.githubusercontent.com/u/1142958?v=4","gravatar_id":"","url":"https://api.github.com/users/benaadams","html_url":"https://github.com/benaadams","followers_url":"https://api.github.com/users/benaadams/followers","following_url":"https://api.github.com/users/benaadams/following{/other_user}","gists_url":"https://api.github.com/users/benaadams/gists{/gist_id}","starred_url":"https://api.github.com/users/benaadams/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benaadams/subscriptions","organizations_url":"https://api.github.com/users/benaadams/orgs","repos_url":"https://api.github.com/users/benaadams/repos","events_url":"https://api.github.com/users/benaadams/events{/privacy}","received_events_url":"https://api.github.com/users/benaadams/received_events","type":"User","site_admin":false},"created_at":"2017-09-04T22:06:09Z","updated_at":"2017-09-04T22:06:09Z","author_association":"COLLABORATOR","body":"Will add the WriteAsync no-copy also"}}
{"actor":{"display_login":"benaadams"}}