{"action":"created","issue":{"url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/8","repository_url":"https://api.github.com/repos/snapview/tungstenite-rs","labels_url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/8/comments","events_url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/8/events","html_url":"https://github.com/snapview/tungstenite-rs/issues/8","id":217337600,"number":8,"title":"Suggestion: use a better data structure for InputBuffer","user":{"login":"bluetech","id":1223550,"avatar_url":"https://avatars0.githubusercontent.com/u/1223550?v=3","gravatar_id":"","url":"https://api.github.com/users/bluetech","html_url":"https://github.com/bluetech","followers_url":"https://api.github.com/users/bluetech/followers","following_url":"https://api.github.com/users/bluetech/following{/other_user}","gists_url":"https://api.github.com/users/bluetech/gists{/gist_id}","starred_url":"https://api.github.com/users/bluetech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bluetech/subscriptions","organizations_url":"https://api.github.com/users/bluetech/orgs","repos_url":"https://api.github.com/users/bluetech/repos","events_url":"https://api.github.com/users/bluetech/events{/privacy}","received_events_url":"https://api.github.com/users/bluetech/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-03-27T18:41:55Z","updated_at":"2017-03-27T18:52:05Z","closed_at":null,"body":"`InputBuffer` currently uses a growable `Vec`. It appends new data, and drains old data.\r\n\r\nThe `drain` part incurs a `memmove` of the `Vec`s content. Since memory copies take up the majority of the runtime, I think the library should try to avoid them when possible. In this case the library can use another data structure for that. The usual one would be a growable ring buffer, this way the `drain` would not incur a copy, only growing/shrinking the buffer would.\r\n\r\nLuckily, the standard library already has an implementation of a growable ring buffer, [`VecDeque`](https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html). So I think it'd be worthwhile to try it and see if my theory is true :)\r\n\r\nOne thing we need to be able to do is to read directly into the buffer, again to avoid copies. For `Vec` it's implemented with the help of `bytes::BufMut::bytes_mut`. But `BufMut` is not implemented for `VecDeque`. I opened https://github.com/carllerche/bytes/issues/94 - maybe it's possible.\r\n\r\n[Side note: the implementation of `InputBuffer::read_from` is in fact not technically safe, because it is actually illegal in Rust to do `Read::read` into an uninitialized buffer. That's because a `Read` implementation is technically free to read the buffer that's passed into it, and reading uninitialized bytes is illegal in Rust. I'm not sure how much I care about that, though - a `Read` implementation which does something like that would be pretty odd.] "},"comment":{"url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/comments/289549201","html_url":"https://github.com/snapview/tungstenite-rs/issues/8#issuecomment-289549201","issue_url":"https://api.github.com/repos/snapview/tungstenite-rs/issues/8","id":289549201,"user":{"login":"agalakhov","id":1681335,"avatar_url":"https://avatars2.githubusercontent.com/u/1681335?v=3","gravatar_id":"","url":"https://api.github.com/users/agalakhov","html_url":"https://github.com/agalakhov","followers_url":"https://api.github.com/users/agalakhov/followers","following_url":"https://api.github.com/users/agalakhov/following{/other_user}","gists_url":"https://api.github.com/users/agalakhov/gists{/gist_id}","starred_url":"https://api.github.com/users/agalakhov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agalakhov/subscriptions","organizations_url":"https://api.github.com/users/agalakhov/orgs","repos_url":"https://api.github.com/users/agalakhov/repos","events_url":"https://api.github.com/users/agalakhov/events{/privacy}","received_events_url":"https://api.github.com/users/agalakhov/received_events","type":"User","site_admin":false},"created_at":"2017-03-27T18:52:05Z","updated_at":"2017-03-27T18:52:05Z","body":"The limitation of Read is, we need a single block of memory to read into. Using a ring buffer results in splitting the free space in two parts. I don't think we can use readv here.\r\n\r\nMy opinion is, instead of optimizing memmove here it were nice to optimize the data consumer to parse all data available. In this case memmove will be called only for a small amount of data and can be neglected. This also probably will fix the UTF-8 issue in Autobahn tests."}}
{"actor":{"display_login":"agalakhov"}}