On Tuesday, 25 November 2025 at 22:31:30 UTC, MrJay wrote:
On Tuesday, 25 November 2025 at 22:19:19 UTC, MrJay wrote:
when you are comparing two languages you have to be careful to
not accidentally add accidental bottlenecks, where you are not
comparing the bottle neck rather than the languages
really didnt like how I explained this to restate it
profiling is quite difficult, and must be done with care
because its very easy to profile a bottleneck rather than the
application or code it self.
even as an array of bytes its 1mb
as bits its 125000 bytes
or 125 kilobytes
and every instruction would be much faster as well, and every
lookup should also be faster
I rewrote my own version of the AOC using a BitArray
I tried to keep the dependencies as low as possible, so more code
than is necessary.
I could also do more optimizations but I wanted the code to at
least be simple.
only optimization I did do is just avoid allocating, and or do
allocations up front in bulk. most of that doesn't matter, this
is still a pretty simple version of the code regardless.
```d
import std.stdio;
import std.bitmanip;
import core.memory;
//correct output 569999
BitArray[1000] lights;
void main() {
GC.disable; // I disable the GC as I know where the
program allocates
start("input.txt");
}
long start(string filename) {
foreach(ref k; lights) {
k.length = 1000; // allocates here
}
auto f = File(filename,"r");
char[] buf; // slightly unnecessary optimization
buf.reserve(64); // line length shouldnt be more than
64, minimizes allocations
while(!f.eof) {
f.readln(buf);
if(buf.length < 5) continue;
parse_line(buf[0..$]);
}
long total;
foreach(ba; lights) total += ba.count;
writeln(total);
return 0;
}
@nogc nothrow :
int index_of(T)(T[] str, T d) {
foreach(i, c; str) {
if(c == d) {
return cast(int) i;
}
}
return -1;
}
int[4] parse_points(char[] line) {
int[2] spaces;
spaces[0] = line.index_of(' ');
spaces[1] = cast(int)(spaces[0]+("through".length+1));
// can do this constant as through is consistent
int[2] p1 = line[0..spaces[0]].parse_point;
int[2] p2 = line[spaces[1]+1..$-1].parse_point;
return [p1[0],p1[1],p2[0],p2[1]];
}
int[2] parse_point(char[] pair) {
int commaloc = pair.index_of(',');
int i1 = pair[0..commaloc].parse_int;
int i2 = pair[commaloc+1..$].parse_int;
return [i1,i2];
}
int parse_int(char[] str) {
import std.math : pow;
int pwr = cast(int) str.length-1;
int total = 0;
foreach(c;str) {
long v = c - '0';
if(v >= 0 && v <= 9) {
v = v*pow(10, pwr);
total += v;
pwr -= 1;
} else {
break;
}
}
return total;
}
void parse_line(char[] line) {
line = line[line.index_of(' ')+1..$]; // removes the
first wort
int[4] points;
bool on = line[0..2] == "on"; // if second word is on
bool off = line[0..3] == "off"; // if second word is off
if(on || off) {
line = line[line.index_of(' ')+1..$];
points = parse_points(line); // I use slices here
no allocations
auto p1 = points[0..2];
auto p2 = points[2..$];
for(int i = p1[0]; i <= p2[0]; i++) {
for(int j = p1[1]; j <= p2[1]; j++) {
lights[i][j] = on; // on is the
boolean on this also decides which op to do
}
}
} else { // if second word is neither
points = parse_points(line); // I use slices here
no allocations
auto p1 = points[0..2];
auto p2 = points[2..$];
for(int i = p1[0]; i <= p2[0]; i++) {
for(int j = p1[1]; j <= p2[1]; j++) {
lights[i].flip(j); // used the flip
function built into BitArray
}
}
}
}
```