Skip to content

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

@avahe-kellenberger

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

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