digitalmars.D.learn - fast way to insert element at index 0
- Assembly (13/13) Jun 22 2015 What's a fast way to insert an element at index 0 of array? now
- Dennis Ritchie (9/22) Jun 22 2015 I think you want to do something like this:
- jkpl (21/34) Jun 22 2015 * Option 1/
- Steven Schveighoffer (7/34) Jun 23 2015 This will fail.
- Baz (4/32) Jun 23 2015 according to the C library, memmove handle overlapps, you
- Steven Schveighoffer (13/44) Jun 23 2015 The above is not memmove, it's slice assignment, which is specifically
- Baz (5/27) Jun 23 2015 ok. i was, wrongly, suposing that this operation uses memmove
- Steven Schveighoffer (4/31) Jun 23 2015 Heh, it was just to demonstrate the error :) The code does a whole lot
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (23/34) Jun 22 2015 If the array is huge, you may find it to be faster to not move any data
What's a fast way to insert an element at index 0 of array? now that the code is working I want to clean this: void push(T val) { T[] t = new T[buffer.length + 1]; t[0] = val; t[1 .. $] = buffer; buffer = t; } I did this because I didn't find any suble built-in data structure that let me insert an item into a specific index at first search. Slist does have insertFron(), exactly what I'm looking for it's a linked list.
Jun 22 2015
On Tuesday, 23 June 2015 at 05:16:23 UTC, Assembly wrote:What's a fast way to insert an element at index 0 of array? now that the code is working I want to clean this: void push(T val) { T[] t = new T[buffer.length + 1]; t[0] = val; t[1 .. $] = buffer; buffer = t; } I did this because I didn't find any suble built-in data structure that let me insert an item into a specific index at first search. Slist does have insertFron(), exactly what I'm looking for it's a linked list.I think you want to do something like this: void main() { import std.algorithm; auto a = [1, 2, 3]; int val = 5; a = val ~ a; // vector.pushFront(); assert(equal(a[], [5, 1, 2, 3])); }
Jun 22 2015
On Tuesday, 23 June 2015 at 05:16:23 UTC, Assembly wrote:What's a fast way to insert an element at index 0 of array? now that the code is working I want to clean this: void push(T val) { T[] t = new T[buffer.length + 1]; t[0] = val; t[1 .. $] = buffer; buffer = t; } I did this because I didn't find any suble built-in data structure that let me insert an item into a specific index at first search. Slist does have insertFron(), exactly what I'm looking for it's a linked list.* Option 1/ if most of the time you have to insert at the beginning, then start reading from the end and append to the end, so that the existing block has not to be moved. You just have to add val at the end. * Option 2/ better way to move the whole block (this can be done with memmove too). --- void push(T val) { buffer.length += 1; buffer[1..$] = buffer[0..$-1]; // or memmove(buffer.ptr + T.sizeof, buffer.ptr, (buffer.length - 1) * T.sizeof); buffer[0] = val; } --- * Option 3/ linked lists are better to insert/move.
Jun 22 2015
On 6/23/15 1:51 AM, jkpl wrote:On Tuesday, 23 June 2015 at 05:16:23 UTC, Assembly wrote:This will fail. http://dlang.org/arrays.html#overlapping-copying I will note, dcollections had a deque, which allowed insertion at the front in O(1) (amortized) time. It basically worked by having 2 arrays front to front. -SteveWhat's a fast way to insert an element at index 0 of array? now that the code is working I want to clean this: void push(T val) { T[] t = new T[buffer.length + 1]; t[0] = val; t[1 .. $] = buffer; buffer = t; } I did this because I didn't find any suble built-in data structure that let me insert an item into a specific index at first search. Slist does have insertFron(), exactly what I'm looking for it's a linked list.* Option 1/ if most of the time you have to insert at the beginning, then start reading from the end and append to the end, so that the existing block has not to be moved. You just have to add val at the end. * Option 2/ better way to move the whole block (this can be done with memmove too). --- void push(T val) { buffer.length += 1; buffer[1..$] = buffer[0..$-1];
Jun 23 2015
On Tuesday, 23 June 2015 at 11:22:31 UTC, Steven Schveighoffer wrote:On 6/23/15 1:51 AM, jkpl wrote:according to the C library, memmove handle overlapps, you mismatch with memcpy which does not.On Tuesday, 23 June 2015 at 05:16:23 UTC, Assembly wrote:This will fail. http://dlang.org/arrays.html#overlapping-copying I will note, dcollections had a deque, which allowed insertion at the front in O(1) (amortized) time. It basically worked by having 2 arrays front to front. -Steve[...]* Option 1/ if most of the time you have to insert at the beginning, then start reading from the end and append to the end, so that the existing block has not to be moved. You just have to add val at the end. * Option 2/ better way to move the whole block (this can be done with memmove too). --- void push(T val) { buffer.length += 1; buffer[1..$] = buffer[0..$-1];
Jun 23 2015
On 6/23/15 8:12 AM, Baz wrote:On Tuesday, 23 June 2015 at 11:22:31 UTC, Steven Schveighoffer wrote:The above is not memmove, it's slice assignment, which is specifically illegal for overlaps: $ cat testsliceassign.d void buffer[100]; void main() { buffer[1..$] = buffer[0..$-1]; } $ dmd testsliceassign.d $ ./testsliceassign object.Error (0): Overlapping arrays in copy: 98 byte(s) overlap of 99 -SteveOn 6/23/15 1:51 AM, jkpl wrote:according to the C library, memmove handle overlapps, you mismatch with memcpy which does not.On Tuesday, 23 June 2015 at 05:16:23 UTC, Assembly wrote:This will fail. http://dlang.org/arrays.html#overlapping-copying I will note, dcollections had a deque, which allowed insertion at the front in O(1) (amortized) time. It basically worked by having 2 arrays front to front.[...]* Option 1/ if most of the time you have to insert at the beginning, then start reading from the end and append to the end, so that the existing block has not to be moved. You just have to add val at the end. * Option 2/ better way to move the whole block (this can be done with memmove too). --- void push(T val) { buffer.length += 1; buffer[1..$] = buffer[0..$-1];
Jun 23 2015
On Tuesday, 23 June 2015 at 13:29:41 UTC, Steven Schveighoffer wrote:On 6/23/15 8:12 AM, Baz wrote:ok. i was, wrongly, suposing that this operation uses memmove under the hood. btw you forgot to grow the array size, if i dare.On Tuesday, 23 June 2015 at 11:22:31 UTC, Steven Schveighoffer wrote:The above is not memmove, it's slice assignment, which is specifically illegal for overlaps: $ cat testsliceassign.d void buffer[100]; void main() { buffer[1..$] = buffer[0..$-1]; } $ dmd testsliceassign.d $ ./testsliceassign object.Error (0): Overlapping arrays in copy: 98 byte(s) overlap of 99 -Steve[...]according to the C library, memmove handle overlapps, you mismatch with memcpy which does not.
Jun 23 2015
On 6/23/15 10:20 AM, Baz wrote:On Tuesday, 23 June 2015 at 13:29:41 UTC, Steven Schveighoffer wrote:Heh, it was just to demonstrate the error :) The code does a whole lot of nothing, actually. -SteveOn 6/23/15 8:12 AM, Baz wrote:ok. i was, wrongly, suposing that this operation uses memmove under the hood. btw you forgot to grow the array size, if i dare.On Tuesday, 23 June 2015 at 11:22:31 UTC, Steven Schveighoffer wrote:The above is not memmove, it's slice assignment, which is specifically illegal for overlaps: $ cat testsliceassign.d void buffer[100]; void main() { buffer[1..$] = buffer[0..$-1]; } $ dmd testsliceassign.d $ ./testsliceassign object.Error (0): Overlapping arrays in copy: 98 byte(s) overlap of 99[...]according to the C library, memmove handle overlapps, you mismatch with memcpy which does not.
Jun 23 2015
On 06/22/2015 10:16 PM, Assembly wrote:> What's a fast way to insert an element at index 0 of array? now that thecode is working I want to clean this: void push(T val) { T[] t = new T[buffer.length + 1]; t[0] = val; t[1 .. $] = buffer; buffer = t; } I did this because I didn't find any suble built-in data structure that let me insert an item into a specific index at first search. Slist does have insertFron(), exactly what I'm looking for it's a linked list.If the array is huge, you may find it to be faster to not move any data at all but treat both that single element and the array as one larger range. chain() does that: import std.algorithm; import std.range; void main() { auto arr = [ 0, 1, 2 ]; auto singleElement = 42.only; auto both = chain(singleElement, arr); assert(both.equal([ 42, 0, 1, 2 ])); // Supports random access as well: assert(both[0] == 42); // ... assert(both[$-1] == 2); } As you can see, although what chain() returns is not an array, it is a RandomAccessRange; so, indexing works just fine. However, do test its performance before using it as some of its operations necessarily do more work than a real array (or slice). Ali
Jun 22 2015