Skip to content

Debug mode - Referencing field copies the object (self hosted backend) #25184

Description

@avahe-kellenberger

Zig Version

0.15.1

Steps to Reproduce and Observed Behavior

I'm not sure if this is a duplicate of #25111 but I didn't think it was, based on the first comment...

The following code (in debug mode, not using llvm) has fn slow running significantly slower than fn fast:

const std = @import("std");

pub fn main() !void {
    var foo: Foo = .init();

    var slow_data: [100]i128 = undefined;
    for (0..100) |i| slow_data[i] = foo.slow();

    var fast_data: [100]i128 = undefined;
    for (0..100) |i| fast_data[i] = foo.fast();

    std.mem.sort(i128, &slow_data, {}, std.sort.asc(i128));
    std.mem.sort(i128, &fast_data, {}, std.sort.asc(i128));

    std.log.err("min: {} - max: {} - median: {}", .{ slow_data[0], slow_data[99], slow_data[49] });
    std.log.err("min: {} - max: {} - median: {}", .{ fast_data[0], fast_data[99], fast_data[49] });
}

const Map = struct {
    pub const Self = @This();
    tile_size: f32,
    data: [144 * 144 * 16]u8 = undefined,
    pub fn init(tile_size: f32) Self {
        return .{ .tile_size = tile_size };
    }
};

const Foo = struct {
    pub const Self = @This();

    map: Map,

    pub fn init() Self {
        return .{ .map = .init(16.0) };
    }

    pub fn slow(self: *Self) i128 {
        const start_time = std.time.nanoTimestamp();
        const map_size = self.map.tile_size;
        _ = map_size;
        return std.time.nanoTimestamp() - start_time;
    }

    pub fn fast(self: *Self) i128 {
        const start_time = std.time.nanoTimestamp();
        const map_size = &(self.map).tile_size;
        _ = map_size;
        return std.time.nanoTimestamp() - start_time;
    }
};
zig run foo.zig -freference-trace
error: min: 5811 - max: 150233 - median: 6301
error: min: 60 - max: 81 - median: 70
zig run -OReleaseSafe foo.zig
error: min: 10 - max: 40 - median: 20
error: min: 10 - max: 30 - median: 20
zig run -fllvm foo.zig
error: min: 20 - max: 140 - median: 30
error: min: 20 - max: 31 - median: 30

I haven't delved into the assembly, but I'm assuming this is causing a copy of Map (used Map.data to emphasize the slowdown)

Expected Behavior

Self hosted backend debug mode should have speeds somewhat similar to debug + llvm, or ReleaseSafe

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions