www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What should I use for concat string into array in loop?

reply Marc <jckj33 gmail.com> writes:
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?
Feb 12 2018
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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."
Feb 12 2018
parent Seb <seb wilzba.ch> writes:
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
Feb 12 2018
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Feb 12 2018
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Feb 12 2018