Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
February 12, 2018 Re: What should I use for concat string into array in loop? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | On Tue, Feb 13, 2018 at 01:58:42AM +0000, Marc via Digitalmars-d-learn wrote: > appender doesn't support string[] so in such case: Why not? This seems to work: import std.array; import std.stdio; void main() { auto app = appender!(string[]); foreach (i; 0 .. 1000) { app.put("abc"); } writeln(app.data); } T -- "You are a very disagreeable person." "NO." |
February 13, 2018 What should I use for concat string into array in loop? | ||||
---|---|---|---|---|
| ||||
appender doesn't support string[] so in such case:
> string[] output;
> for(...) {
> if(...) {
> output ~= str;
> }
> }
Looking for avoid as many immediate allocations as possible, what should I use?
|
February 12, 2018 Re: What should I use for concat string into array in loop? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | On Tuesday, February 13, 2018 01:58:42 Marc via Digitalmars-d-learn wrote:
> appender doesn't support string[] so in such case:
> > string[] output;
> > for(...) {
> >
> > if(...) {
> >
> > output ~= str;
> >
> > }
> >
> > }
>
> Looking for avoid as many immediate allocations as possible, what should I use?
Well, the space allocation for dynamic arrays works the same way that it does with something like vector in C++ or ArrayList in Java. So, it's amortized constant cost. So, using ~= is just fine.
That being said, every time that ~= is called, the runtime has to check whether there's room to append in place or whether it has to reallocate the array. In most cases, if you're appending in a loop, there's going to be room, but the check isn't necessarily as cheap as would be nice. So, as an alternative, there's std.array.Appender/appender, which does some of the checks itself instead of calling the runtime, which speeds it up. So, you may want to use Appender, but ~= is going to work just fine.
There's also the reserve function for reserving a minimum capacity for the array, so if you know roughly how much you're going to need, you can call reserve to tell it to allocate at least that much capacity up front and reduce the number of allocations - even eliminate them if you really do know the required capacity up front, since if the capacity is large enough, the call to reserve will have allocated the necessary memory, and none of the append calls will actually end up allocating.
- Jonathan M Davis
|
February 12, 2018 Re: What should I use for concat string into array in loop? | ||||
---|---|---|---|---|
| ||||
On Monday, February 12, 2018 17:56:45 H. S. Teoh via Digitalmars-d-learn wrote: > On Tue, Feb 13, 2018 at 01:58:42AM +0000, Marc via Digitalmars-d-learn wrote: > > appender doesn't support string[] so in such case: > Why not? This seems to work: > > import std.array; > import std.stdio; > void main() { > auto app = appender!(string[]); > foreach (i; 0 .. 1000) { > app.put("abc"); > } > writeln(app.data); > } LOL. I read his message too quickly and missed that he had problem with appender and told him about appender and some alternatives. I assume that his problem is that he didn't use parens. If he tried appender!string[], then it's not going to work, because the [] ends up being associated with the result of appender!string instead of being associated with string and the passed to appender. - Jonathan M Davis |
February 13, 2018 Re: What should I use for concat string into array in loop? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Tuesday, 13 February 2018 at 01:56:45 UTC, H. S. Teoh wrote: > On Tue, Feb 13, 2018 at 01:58:42AM +0000, Marc via Digitalmars-d-learn wrote: >> appender doesn't support string[] so in such case: > > Why not? This seems to work: > > import std.array; > import std.stdio; > void main() { > auto app = appender!(string[]); > foreach (i; 0 .. 1000) { > app.put("abc"); > } > writeln(app.data); > } > > > T Or simply don't allocate at all: --- import std.algorithm, std.range, std.stdio; void main() { "abc".repeat(1000).joiner.writeln; } --- https://run.dlang.io/is/ubGZwJ writeln isn't @nogc atm, but if you want to prove that no allocation happens, fallback to printf: ---- import core.stdc.stdio, std.algorithm, std.range, std.stdio; void main() @nogc { "abc".repeat(1000).each!(s => printf("%.*s", s.length, s.ptr)); } --- https://run.dlang.io/is/V7PWXj |
Copyright © 1999-2021 by the D Language Foundation