In my previous post I asked why copyfile
is slower than the cp
Terminal command. In this other post I asked how I can make copyfile
faster by changing the block size.
Now I discovered that the cp
implementation on macOS is open source and that when copying regular files it doesn't use copyfile
but fcopyfile
. In a test I noticed that fcopyfile
by default seems to be faster than copyfile
.
When copying a 7 GB file I get about the same results I observed when comparing filecopy
to cp
:
copyfile
: 4.70 sfcopyfile
: 3.44 s
When setting a block size of 16_777_216
, copyfile
becomes faster than fcopyfile
:
copyfile
: 3.20 sfcopyfile
: 3.53 s
Is this expected and why is it so? I would have expected that they both have the same performance, and when changing the block size they would still have the same performance.
Here is the test code. Change #if true
to #if false
to switch from fcopyfile
to copyfile
:
import Foundation
import System
let source = "/path/to/source"
let destination = "/path/to/destination"
#if true
let state = copyfile_state_alloc()
defer {
copyfile_state_free(state)
}
//var bsize = 16_777_216
//copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize)
let sourceFd = try! FileDescriptor.open(source, .readOnly)
let destinationFd = try! FileDescriptor.open(destination, .writeOnly)
if fcopyfile(sourceFd.rawValue, destinationFd.rawValue, state, copyfile_flags_t(COPYFILE_ALL | COPYFILE_NOFOLLOW | COPYFILE_EXCL | COPYFILE_UNLINK)) != 0 {
print(NSError(domain: NSPOSIXErrorDomain, code: Int(errno)))
}
try! sourceFd.close()
try! destinationFd.close()
#else
source.withCString { sourcePath in
destination.withCString { destinationPath in
let state = copyfile_state_alloc()
defer {
copyfile_state_free(state)
}
// var bsize = 16_777_216
// copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize)
if copyfile(sourcePath, destinationPath, state, copyfile_flags_t(COPYFILE_ALL | COPYFILE_NOFOLLOW | COPYFILE_EXCL | COPYFILE_UNLINK)) != 0 {
print(NSError(domain: NSPOSIXErrorDomain, code: Int(errno)))
}
}
}
#endif