Skip to content

on macOS, std.fs.deleteTree() is 40% slower than rm -rf #13048

@Jarred-Sumner

Description

@Jarred-Sumner

Zig Version

0.10.0-dev.2822+b79884eaf

Steps to Reproduce

Zig (zig build-exe -OReleaseFast rm.zig)

const std = @import("std");
pub fn main() anyerror!void {
    try std.fs.cwd().deleteTree(std.mem.span(std.os.argv[std.mem.span(std.os.argv).len - 1]));
}

C (clang -O3 rm.c) using removefile (which turns out to be slower or the same as rm)

#include <errno.h>
#include <removefile.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  if (argc < 2) {
    fprintf(stderr, "usage: rm path");
    return 1;
  }

  if (removefile(argv[argc - 1], NULL, REMOVEFILE_RECURSIVE)) {
    fprintf(stderr, "removefile failed: %s", strerror(errno));
    return 1;
  }

  return 0;
}

Assuming node_modules is a folder with lots and lots of files and directories (~700 MB, xxx,xxx files)

hyperfine "./rm node_modules_copy" "./a.out node_modules_copy" "rm -rf node_modules_copy" --prepare="cp -r node_modules node_modules_copy"

Expected Behavior

Zig should perform similarly or better

Actual Behavior

hyperfine "./rm node_modules_copy" "./a.out node_modules_copy" "rm -rf node_modules_copy" --prepare="cp -r node_modules node_modules_copy"
Benchmark 1: ./rm node_modules_copy
  Time (mean ± σ):      5.796 s ±  0.681 s    [User: 0.041 s, System: 5.363 s]
  Range (minmax):    4.457 s6.761 s    10 runs
 
Benchmark 2: ./a.out node_modules_copy
  Time (mean ± σ):      4.614 s ±  0.536 s    [User: 0.040 s, System: 4.226 s]
  Range (minmax):    4.170 s6.090 s    10 runs
 
  Warning: The first benchmarking run for this command was significantly slower than the rest (6.090 s). This could be caused by (filesystem) caches that were not filled until after the first run. You should consider using the '--warmup' option to fill those caches before the actual benchmark. Alternatively, use the '--prepare' option to clear the caches before each timing run.
 
Benchmark 3: rm -rf node_modules_copy
  Time (mean ± σ):      4.145 s ±  0.198 s    [User: 0.046 s, System: 3.750 s]
  Range (minmax):    3.894 s4.420 s    10 runs
 
Summary
  'rm -rf node_modules_copy' ran
    1.11 ± 0.14 times faster than './a.out node_modules_copy'
    1.40 ± 0.18 times faster than './rm node_modules_copy'

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorstandard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions