What's the point of static arrays ?
Ali Çehreli
acehreli at yahoo.com
Thu Jul 9 14:30:48 UTC 2020
On 7/9/20 5:12 AM, wjoe wrote:
> Considering the many downsides why would I ever want to choose a static
> over a dynamic array ?
>
In addition to what others said, dynamic arrays can be more expensive
both in space and time.
Time: Dynamic array elements are accessed through an extra pointer
compared to static arrays. Depending on the usage pattern of the data,
that extra indirection may be slower (e.g. due to the extra load on the
CPU's cache).
Space: Every dynamic array is represented by the pair of one pointer
(void*) one length (size_t) e.g. 2 * 8 = 16 bytes on a 64-bit system.
Assuming the array is just 3 floats, which is a common type used for
RGB, 3D coordinates, etc. (3 * 4 = 12 bytes), then those 16 bytes are
more than the data itself.
I wrote the following program (as a fun morning exercise, before coffee
:o) ) to display bytes used by different kinds of variables:
import std.stdio;
import std.range;
import std.algorithm;
import std.traits;
size_t bytesUsed(T)(T var) {
static if (isDynamicArray!T) {
enum dynamicArrayOverhead = (void[]).sizeof;
// Double check:
static assert (dynamicArrayOverhead == size_t.sizeof + (void*).sizeof);
return dynamicArrayOverhead + var.map!(element =>
bytesUsed(element)).sum;
} else static if (isAssociativeArray!T) {
static assert (false, "I don't know the implementation of AAs.");
} else static if (is (T == struct)) {
// BUG: Ignores alignment
size_t total;
foreach (member; var.tupleof) {
total += bytesUsed(member);
}
return total;
} else static if (is (T == class)) {
// BUG: Ignores alignment
size_t total;
foreach (member; var.tupleof) {
total += bytesUsed(member);
}
enum classOverhead = (void*).sizeof * 2;
return classOverhead + total;
} else {
return var.sizeof;
}
// BUG: union?
}
unittest {
struct S {
int[] arr;
void* ptr;
}
assert(bytesUsed(S([1, 2, 3])) == size_t.sizeof + (void*).sizeof + 3
* int.sizeof + 8);
}
void info(alias var)() {
writefln!"'%s' is %s and uses %s bytes."(var.stringof,
typeof(var).stringof, bytesUsed(var));
}
void main() {
// This is an efficient data structure:
alias Color = float[3]; // red, green, blue
alias DayColors = Color[7];
// Comparing it to the dynamic array equivalent:
DayColors a;
auto b = makeDayColors();
info!a;
info!b;
}
float[] makeColor() {
// Syntax confusion alert: Return type is *not* a static array. :/
return new float[3];
}
float[][] makeDayColors() {
float[][] result = new float[][7];
foreach (ref e; result) {
e = makeColor();
}
return result;
}
Ali
More information about the Digitalmars-d-learn
mailing list