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

Reply via email to