[webkit-changes] cvs commit: WebKit/Misc.subproj WebNSURLExtras.m

Geoffrey ggaren at opensource.apple.com
Fri Oct 21 11:43:12 PDT 2005


ggaren      05/10/21 11:43:12

  Modified:    .        ChangeLog
               Misc.subproj WebNSURLExtras.m
  Log:
          Patch by TimO, Reviewed by hyatt, tested and landed by me.
  
          Found what appears to be a misguided optimization that actually causes a measurable performance problem.
          A fixed-size buffer was allocated on the stack to pass into CFURLGetBytes(), presumably to avoid malloc()
          for URLs less than 2048 bytes.  There was also a fallback which malloc()'ed a buffer in case the fixed-size
          buffer was too small to hold the URL's bytes.  This malloc()'ed buffer was then wrapped in an NSData using
          +dataWithBytesNoCopy:length:, avoiding a memory copy (yay!)
  
          The problem with this approach is two-fold:
  
          1. Regardless of how the buffer was allocated and filled, it is immediately wrapped in an NSData using
          +dataWithBytes:length:, which copies the input bytes.  This is pretty much unavoidable; we need to get
          the data into a malloc()'ed buffer to return it to the caller, unless the caller provides its own storage
          (which would be super inconvenient).
  
          2. The size of the fixed buffer was large enough that it fit most (if not all) URLs involved in our Page
          Load Test.  This means the unintentionally-inefficient case was by far the most *common* case!
  
          My fix is to malloc() the buffer from the start, and then use +[NSData dataWithBytes:length:freeWhenDone:]
          to wrap the buffer in an NSData.  This avoids a memory copy for the normal case where a URL is less than
          2048 bytes, and keeps the efficient behavior for the uncommon long URL case.
  
          * Misc.subproj/WebNSURLExtras.m:
          (-[NSURL _web_originalData]):
  
  Revision  Changes    Path
  1.3356    +27 -0     WebKit/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebKit/ChangeLog,v
  retrieving revision 1.3355
  retrieving revision 1.3356
  diff -u -r1.3355 -r1.3356
  --- ChangeLog	21 Oct 2005 16:35:22 -0000	1.3355
  +++ ChangeLog	21 Oct 2005 18:42:58 -0000	1.3356
  @@ -1,3 +1,30 @@
  +2005-10-21  Geoffrey Garen  <ggaren at apple.com>
  +
  +        Patch by TimO, Reviewed by hyatt, tested and landed by me.
  +
  +        Found what appears to be a misguided optimization that actually causes a measurable performance problem.
  +        A fixed-size buffer was allocated on the stack to pass into CFURLGetBytes(), presumably to avoid malloc()
  +        for URLs less than 2048 bytes.  There was also a fallback which malloc()'ed a buffer in case the fixed-size
  +        buffer was too small to hold the URL's bytes.  This malloc()'ed buffer was then wrapped in an NSData using
  +        +dataWithBytesNoCopy:length:, avoiding a memory copy (yay!)
  +
  +        The problem with this approach is two-fold:
  +    
  +        1. Regardless of how the buffer was allocated and filled, it is immediately wrapped in an NSData using
  +        +dataWithBytes:length:, which copies the input bytes.  This is pretty much unavoidable; we need to get
  +        the data into a malloc()'ed buffer to return it to the caller, unless the caller provides its own storage
  +        (which would be super inconvenient).
  +    
  +        2. The size of the fixed buffer was large enough that it fit most (if not all) URLs involved in our Page
  +        Load Test.  This means the unintentionally-inefficient case was by far the most *common* case!
  +        
  +        My fix is to malloc() the buffer from the start, and then use +[NSData dataWithBytes:length:freeWhenDone:]
  +        to wrap the buffer in an NSData.  This avoids a memory copy for the normal case where a URL is less than
  +        2048 bytes, and keeps the efficient behavior for the uncommon long URL case.
  +
  +        * Misc.subproj/WebNSURLExtras.m:
  +        (-[NSURL _web_originalData]):
  +
   2005-10-21  Mitz Pettel  <opendarwin.org at mitzpettel.com>
   
           Reviewed and landed by Darin.
  
  
  
  1.39      +9 -14     WebKit/Misc.subproj/WebNSURLExtras.m
  
  Index: WebNSURLExtras.m
  ===================================================================
  RCS file: /cvs/root/WebKit/Misc.subproj/WebNSURLExtras.m,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- WebNSURLExtras.m	14 Jul 2005 02:43:51 -0000	1.38
  +++ WebNSURLExtras.m	21 Oct 2005 18:43:11 -0000	1.39
  @@ -382,28 +382,23 @@
   
   - (NSData *)_web_originalData
   {
  -    NSData *data = nil;
  -
  -    UInt8 static_buffer[URL_BYTES_BUFFER_LENGTH];
  -    CFIndex bytesFilled = CFURLGetBytes((CFURLRef)self, static_buffer, URL_BYTES_BUFFER_LENGTH);
  -    if (bytesFilled != -1) {
  -        data = [NSData dataWithBytes:static_buffer length:bytesFilled];
  -    }
  -    else {
  +    UInt8 *buffer = (UInt8 *)malloc(URL_BYTES_BUFFER_LENGTH);
  +    CFIndex bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, URL_BYTES_BUFFER_LENGTH);
  +    if (bytesFilled == -1) {
           CFIndex bytesToAllocate = CFURLGetBytes((CFURLRef)self, NULL, 0);
  -        UInt8 *buffer = malloc(bytesToAllocate);
  +        buffer = (UInt8 *)realloc(buffer, bytesToAllocate);
           bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, bytesToAllocate);
           ASSERT(bytesFilled == bytesToAllocate);
  -        // buffer is adopted by the NSData
  -        data = [NSData dataWithBytesNoCopy:buffer length:bytesFilled];
       }
  -
  +    
  +    // buffer is adopted by the NSData
  +    NSData *data = [NSData dataWithBytesNoCopy:buffer length:bytesFilled freeWhenDone:YES];
  +    
       NSURL *baseURL = (NSURL *)CFURLGetBaseURL((CFURLRef)self);
       if (baseURL) {
           NSURL *URL = [NSURL _web_URLWithData:data relativeToURL:baseURL];
           return [URL _web_originalData];
  -    }
  -    else {
  +    } else {
           return data;
       }
   }
  
  
  



More information about the webkit-changes mailing list