{"action":"created","issue":{"url":"https://api.github.com/repos/zeromq/netmq/issues/400","labels_url":"https://api.github.com/repos/zeromq/netmq/issues/400/labels{/name}","comments_url":"https://api.github.com/repos/zeromq/netmq/issues/400/comments","events_url":"https://api.github.com/repos/zeromq/netmq/issues/400/events","html_url":"https://github.com/zeromq/netmq/pull/400","id":116101465,"number":400,"title":"Add offset to Msg to support ArraySegment-like API with `byte[], offset, length`","user":{"login":"buybackoff","id":489852,"avatar_url":"https://avatars.githubusercontent.com/u/489852?v=3","gravatar_id":"","url":"https://api.github.com/users/buybackoff","html_url":"https://github.com/buybackoff","followers_url":"https://api.github.com/users/buybackoff/followers","following_url":"https://api.github.com/users/buybackoff/following{/other_user}","gists_url":"https://api.github.com/users/buybackoff/gists{/gist_id}","starred_url":"https://api.github.com/users/buybackoff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buybackoff/subscriptions","organizations_url":"https://api.github.com/users/buybackoff/orgs","repos_url":"https://api.github.com/users/buybackoff/repos","events_url":"https://api.github.com/users/buybackoff/events{/privacy}","received_events_url":"https://api.github.com/users/buybackoff/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-11-10T12:56:49Z","updated_at":"2015-11-15T10:04:57Z","closed_at":"2015-11-15T09:59:26Z","pull_request":{"url":"https://api.github.com/repos/zeromq/netmq/pulls/400","html_url":"https://github.com/zeromq/netmq/pull/400","diff_url":"https://github.com/zeromq/netmq/pull/400.diff","patch_url":"https://github.com/zeromq/netmq/pull/400.patch"},"body":"This is for discussion at this stage - to ask what do you think about such a change?\r\n\r\nI have noticed that most extensions for sending data make additional copy of data even if it is supplied as `byte[]`. But even in the lowest level `Send(ref msg)` and in Msg implementation, currently there is no support for `offset` of a `byte[]`, only its `length`.  However, `byte[] data, int offset, int length` is the standard pattern used almost everywhere in .NET. `ArraySegment<byte>` is an equivalent to the trio and is just a struct around `byte[]` with two fields, it is used in MSFT API with WebSockets. Without offsets, we are forced to copy arrays one more time if payload starts at not zero (which is not a rare case when the whole system is designed for zero-copy when possible).\r\n\r\nIt looks like initially NetMQ was designed after ZeroMQ, but in C/C++ they work with pointers + length, any offset could be applied by pointer arithmetic. In .NET world, if a payload is placed within a buffer at some offset, we have to copy it to use the initial NetMQ APIs that had ignored offsets. With this commit, Msg supports an offset property and behaves mostly like ArraySegment. \r\n\r\nAll tests pass. Performance impact is non-conclusive based on SimpleTests project. Need more evaluation, mostly depends on the use case - if input data is mostly like ArraySegment<byte>/buffers with non-zero offsets then zero-copy could be beneficial, especially for IPC.\r\n\r\nNext step could be to add implicit conversion to/from `ArraySegment<byte>/Msg` and add convenient extensions for `ArraySegment<byte>`."},"comment":{"url":"https://api.github.com/repos/zeromq/netmq/issues/comments/156798150","html_url":"https://github.com/zeromq/netmq/pull/400#issuecomment-156798150","issue_url":"https://api.github.com/repos/zeromq/netmq/issues/400","id":156798150,"user":{"login":"buybackoff","id":489852,"avatar_url":"https://avatars.githubusercontent.com/u/489852?v=3","gravatar_id":"","url":"https://api.github.com/users/buybackoff","html_url":"https://github.com/buybackoff","followers_url":"https://api.github.com/users/buybackoff/followers","following_url":"https://api.github.com/users/buybackoff/following{/other_user}","gists_url":"https://api.github.com/users/buybackoff/gists{/gist_id}","starred_url":"https://api.github.com/users/buybackoff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buybackoff/subscriptions","organizations_url":"https://api.github.com/users/buybackoff/orgs","repos_url":"https://api.github.com/users/buybackoff/repos","events_url":"https://api.github.com/users/buybackoff/events{/privacy}","received_events_url":"https://api.github.com/users/buybackoff/received_events","type":"User","site_admin":false},"created_at":"2015-11-15T10:04:57Z","updated_at":"2015-11-15T10:04:57Z","body":"Great, thanks! All existing users have offset 0 everywhere, so it kind of safe for now. Will add a test that ensures working offset over TCP later."}}