Lisp like lists and a problem with TANGO fromStringz

bearophile bearophileHUGS at lycos.com
Mon Mar 3 08:04:12 PST 2008


To: Newsgroups: digitalmars.D
Subject: Re: Lisp like lists and a problem with TANGO fromStringz

Oskar Linde>Here is a way to reserve space for arrays:<

I did try a function equal to that one, but have you timed it? My timing results don't show any advantage of using such reserve.

------------------------------

D code:

// this D code is written to look as much as possible as the C++ version
import std.stdio: printf;
import std.c.time: clock, CLOCKS_PER_SEC, time_t;
import std.conv: toInt;

double myclock() {
    time_t t = clock();
    if (t == -1)
        return 0.0;
    else
        return t/cast(double)CLOCKS_PER_SEC;
}

void reserve(T)(ref T[] arr, int len) {
    // int rather than size_t due to IFTI sensitivity
    if (len > arr.length) {
        auto t = arr.length;
        arr.length = len;
        arr.length = t;
    }
}

int main(string[] argv) {
    int n = toInt(argv[1]);
    double t = myclock();

    switch (argv[2][0]) {
        case '1':
            int[] a;
            for (int i = 0; i < n; ++i)
                a ~= i;
            break;
        case '2':
            int[] a;
            a.reserve(n);
            for (int i = 0; i < n; ++i)
                a ~= i;
            break;
        case '3':
            auto a = new int[n];
            for (int i = 0; i < n; ++i)
                a[i] = i;
            break;
    }

    printf("%.3f s\n", myclock() - t);
    return 0;
}


------------------------------

C++ code:

#include <stdio.h>
#include <time.h>
#include <vector>

using namespace std;

double myclock() {
    time_t t = clock();
    if (t == -1)
        return 0.0;
    else
        return t/(double)CLOCKS_PER_SEC;
}

int main(int argc, char **argv) {
    int n = atoi(argv[1]);
    double t = myclock();

    switch (argv[2][0]) {
        case '1': {
            vector<int> a;
            for (int i = 0; i < n; ++i)
                a.push_back(i);
            break;
        }
        case '2': {
            vector<int> a;
            a.reserve(n);
            for (int i = 0; i < n; ++i)
                a.push_back(i);
            break;
        }
        case '3': {
            vector<int> a(n);
            a.reserve(n);
            for (int i = 0; i < n; ++i)
                a[i] = i;
            break;
        }
    }

    printf("%.3f s\n", myclock() - t);
    return 0;
}

-----------------------------------

OUTPUT TIMINGS:

DMD 1.026, N = 12_000_000:
  append:            3.3 s
  reserve + append:  3.3 s
  allocate + assign: 1.0 s

C++ MinGW 4.2.1, N = 12_000_000, best of 3:
  append:            1.4 s
  reserve + append:  0.5 s
  allocate + assign: 1.0 s

C++ compiled with -O3 -s
DMD compiled with -O -release -inline
Win on Pentium3 CPU.

Notes:
- All timings are best of 3, rounded to 2 significant digits.
- I don't understand how in C++ the append() can twice faster than the assign.

Bye,
bearophile



More information about the Digitalmars-d mailing list