Thanks for your response, > Given the right conditions, NSFileWrapper can make writing vastly more > efficient by writing hard links for unchanged files, rather than recreating > them afresh. Have you determined whether this is happening at all? Currently I am trying to figure out what those conditions are :)
I ran the "Directory I/O" instrument in Instruments.app and it seems that NSFileWrapper links all large files within my document package: 0 libsystem_kernel.dylib link 1 Foundation -[NSFileWrapper writeToURL:options:originalContentsURL:error:] 2 Foundation -[NSFileWrapper _writeContentsToURL:path:originalContentsURL:tryHardLinking:didHardLinking:error:] 3 Foundation -[NSFileWrapper writeToURL:options:originalContentsURL:error:] 4 AppKit -[NSDocument writeToURL:ofType:error:] 5 AppKit -[NSDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:] 6 AppKit -[NSDocument _writeSafelyToURL:ofType:forSaveOperation:forceTemporaryDirectory:error:] 7 AppKit -[NSDocument _writeSafelyToURL:ofType:forSaveOperation:error:] 8 AppKit -[NSDocument writeSafelyToURL:ofType:forSaveOperation:error:] 9 AppKit __block_global_90 But nonetheless, NSDocument preserves versions for the whole package content at every save (call stack obtained with the "Reads/Writes" instrument): Read: 0 libsystem_kernel.dylib read 1 libcopyfile.dylib copyfile 2 libcopyfile.dylib copyfile 3 GenerationalStorage GSAddPathAsGeneration 4 GenerationalStorage _AddGenerationInternal 5 GenerationalStorage GSLibraryAddGenerationWithOptionsByCopyingFile 6 Foundation +[NSFileVersion(NSPrivate) _addVersionOfItemAtURL:withContentsOfURL:options:temporaryStorageIdentifier:error:] 7 AppKit -[NSDocument _preserveContentsOfURL:forURL:reason:comment:options:error:] 8 AppKit -[NSDocument _preserveContentsIfNecessaryAfterWriting:toURL:forSaveOperation:version:error:] 9 AppKit __block_global_98 Write: 0 libsystem_kernel.dylib write 1 libcopyfile.dylib copyfile 2 libcopyfile.dylib copyfile 3 GenerationalStorage GSAddPathAsGeneration 4 GenerationalStorage _AddGenerationInternal 5 GenerationalStorage GSLibraryAddGenerationWithOptionsByCopyingFile 6 Foundation +[NSFileVersion(NSPrivate) _addVersionOfItemAtURL:withContentsOfURL:options:temporaryStorageIdentifier:error:] 7 AppKit -[NSDocument _preserveContentsOfURL:forURL:reason:comment:options:error:] 8 AppKit -[NSDocument _preserveContentsIfNecessaryAfterWriting:toURL:forSaveOperation:version:error:] 9 AppKit __block_global_98 > In my experience Versions tends to be pretty inefficient about its work. I wonder what NSDocument's private _preserveContentsIfNecessaryAfterWriting (see above call stack) uses to determine whether a file has to be copied or not. > Are you seeing it block the main thread though? That can generally be > avoided. No. Saving and Version preservation are off the main thread. That's why I almost didn't notice the vast amount of copying that's going on after each save. My usage of NSDocument & file packages seems to be straightforward. I didn't overwrite any of the write* methods, I keep a root file wrapper for the lifetime of each NSDocument instance, ... What am I doing wrong? There must be a way to avoid this unnecessary copying... with kind regards, Thomas On 04.02.2013, at 15:12, Mike Abdullah <cocoa...@mikeabdullah.net> wrote: > > On 30 Jan 2013, at 15:53, Thomas Zoechling <thomas.zoechl...@gmx.at> wrote: > >> Hello, >> >> My NSDocument based app uses packages with the following structure: >> >> - document.package >> +- metadata.plist (small, mutable) >> +- large0.file (large, immutable) >> +- large1.file (large, immutable) >> +- large2.file (large, immutable) >> >> While the metadata.plist file can change any time, all large files are >> created once and then stay as they are. >> As my "large0-2" files can be several gigabytes, I try to carefully avoid >> unnecessary IO by using document packages with NSFileWrapper. >> My package reading/writing methods resemble the ones in the "Document >> Package with iCloud" sample (But I don't use iCloud): >> http://developer.apple.com/library/mac/#samplecode/PackagedDocument/ >> I appended the relevant parts of my code at the end of this message. >> >> With this setup, I was hoping that the occasions where the document >> architecture has to copy the whole bundle are reduced to: >> - File duplication >> - Moves to another volume >> >> But after investigating file activity with Instruments.app, it turned out >> that my app is reading and writing chunks of my unmodified, immutable & >> large files during each save. >> It seems that the copying is related to document revisions (a.k.a. Versions). >> Instruments logs hundreds of IO operations in the form of: >> # Caller Function FD Path Bytes >> ... >> 70 copyfile read 22 document.package/large0.file 1048576 >> 71 copyfile write 23 >> /.vol/16777218/2/.DocumentRevisions-V100/staging/adding.Wohcjo4i/4772FAAA-78D3-44A9-9412-A2D651B6EB5A.package/large0.file >> 1048576 >> 70 copyfile read 22 document.package/large0.file 1048576 >> 71 copyfile write 23 >> /.vol/16777218/2/.DocumentRevisions-V100/staging/adding.Wohcjo4i/4772FAAA-78D3-44A9-9412-A2D651B6EB5A.package/large0.file >> 1048576 >> 70 copyfile read 22 document.package/large0.file 1048576 >> 71 copyfile write 23 >> /.vol/16777218/2/.DocumentRevisions-V100/staging/adding.Wohcjo4i/4772FAAA-78D3-44A9-9412-A2D651B6EB5A.package/large0.file >> 1048576 >> ... >> >> How can I tell Versions that the only file that constantly changes within my >> document.package is metadata.info? (Without turning off document revisions >> altogether) >> I am targetting 10.8 (with sandboxing enabled) and also adopted async saving >> and autosavesInPlace. > > Given the right conditions, NSFileWrapper can make writing vastly more > efficient by writing hard links for unchanged files, rather than recreating > them afresh. Have you determined whether this is happening at all? > > In my experience Versions tends to be pretty inefficient about its work. Are > you seeing it block the main thread though? That can generally be avoided. > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com