Based on the answer about rename
;
python3 \
-c "from os import rename; from sys import argv; rename(argv[1], argv[2])" \
$original $temp
seems the fastest for this computer's situation.
it shouldn't be. But here we are.
I'm on macOS Sequoia, 15.2 -- on an encrypted drive using APFS. in VM testing, encryption doesn't have a measurable effect on these times, but it appears moreso that the design of APFS, via the Global Lock: https://gregoryszorc.com/blog/2018/10/29/global-kernel-locks-in-apfs/ is what is slowing things down.
There is also this bug report to openradar: https://openradar.me/45648013
So, we must use tricks to delete things to try to become as fast as ext4 or other reasonable file systems.
This is my situation:
mv
:❯ time ( mv node_modules nm )
real 0m7.578s
user 0m0.001s
sys 0m0.003s
rm
aka move out of existence.
my ultimate goal anyway is deleting
❯ time ( rm -rf node_modules )
real 0m17.763s
user 0m0.132s
sys 0m11.539s
rsync
❯ time ( rsync -av --delete $(mktemp -d)/ ./node_modules )
Transfer starting: 1 files
sent 79 bytes received 26 bytes 70 bytes/sec
total size is 0 speedup is 0.00
real 0m16.208s
user 0m0.376s
sys 0m11.505s
I'm surprised mv
isn't instant -- because it should just be an inode update, yeah?
In addition to the openradar issue, it does seem like others have noticed this problem:
But maybe, mac folks don't typically work in large projects? maybe they just put up with it because "mac is good"? don't know how fast things can be? idk. it's been weird.
@fravadona suggested I disable my AV.
I have actually. things used to be way worse -- 2-4x worse. The AV used was MalwareBytes, and ... well, malware is right in the name... so... if you have a choice of AV... probably don't want that one.
There is still more Software on here for me to test:
While I can't disable these things (I don't own the hardware I'm testing on), I can boot up a macOS VM and run the same test:
Here are the results:
mv
time ( mv node_modules nm.bak )
real 0m0.011s
rm -rf
time ( rm -rf node_modules )
real 0m12.812s
so... that's kind nuts.
mv
has to deal with moves across physical partitions which you don't need.
From man mv
:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move.
Take a look at man 2 rename
which is exposed by, eg, python's os.rename.
The operation may fail if src and dst are on different filesystems. Use
shutil.move()
to support moves to a different filesystem.