1

I am writing an app that contains a small benchmark for I/O operations. For write operations, I am using a 'FileHandle' which works pretty well. I am testing my old USB stick and my calculation results in values of roughly 20MB/s which seems correct.

However, when reading, the values jump up to 8 GB/s. Although I would love to have an USB stick that fast...I think this has to do with some sort of cacheing.

Here is the code that I am using (some bits were removed):

guard let handle = FileHandle(forUpdatingAtPath: url.path) else { return }

let data = Data(repeating: 0, count: 2 * 1024 * 1024)

var startTime = Date.timestamp

// Write Test
while Date.timestamp - startTime < 5.0
{
    handle.write(data)
    try? handle.synchronize()

    // ...
}

// Go back to beginning of file.
try? handle.seek(toOffset: 0)
        
// Remove everything at the end of the file
try? handle.truncate(atOffset: blockSize)

startTime = Date.timestamp

// Read Test
while Date.timestamp - startTime < 5.0
{
    autoreleasepool
    {
        if let handle = try? FileHandle(forReadingFrom: fileUrl), let data = try? handle.readToEnd()
        {
            let count = UInt64(data.count)
                    
            self.readData += count
            self.totalReadData += count

            handle.close()
        }

        // I also tried FileManager.default.contents(atPath: ) - same result
    }
}

I also tried this piece of code (it's either from Martin R. here on SO or from Quinn on the Apple forums):

let fd = open(fileUrl.path, O_RDONLY)
_ = fcntl(fd, F_NOCACHE, 1)

var buffer = Data(count: 1024 * 1024)
buffer.withUnsafeMutableBytes { ptr in
    let amount = read(fd, ptr.baseAddress, ptr.count)

    self.readData += UInt64(amount)
    self.totalReadData += UInt64(amount)
}

close(fd)

The code itself works...but there is still cacheing.

TL;DR How can I disable cacheing when writing to and reading from a file using Swift?

Regards

inexcitus
  • 2,471
  • 2
  • 26
  • 41

0 Answers0