Changeset 288463 in webkit


Ignore:
Timestamp:
Jan 24, 2022 1:12:37 PM (6 months ago)
Author:
youenn@apple.com
Message:

file.stream() is slow and CPU-bound
https://bugs.webkit.org/show_bug.cgi?id=235448

Reviewed by Alex Christensen.

We introduce a ReadAsBinaryChunks mode to prevent storing the whole file in memory.
Use this in Blob stream implementation.
The new implementation is much faster for big files given it does not need to keep in memory the whole file.
Covered by existing tests.

  • fileapi/Blob.cpp:
  • fileapi/FileReaderLoader.cpp:
  • fileapi/FileReaderLoader.h:
  • fileapi/FileReaderLoaderClient.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r288462 r288463  
     12022-01-24  Youenn Fablet  <youenn@apple.com>
     2
     3        file.stream() is slow and CPU-bound
     4        https://bugs.webkit.org/show_bug.cgi?id=235448
     5
     6        Reviewed by Alex Christensen.
     7
     8        We introduce a ReadAsBinaryChunks mode to prevent storing the whole file in memory.
     9        Use this in Blob stream implementation.
     10        The new implementation is much faster for big files given it does not need to keep in memory the whole file.
     11        Covered by existing tests.
     12
     13        * fileapi/Blob.cpp:
     14        * fileapi/FileReaderLoader.cpp:
     15        * fileapi/FileReaderLoader.h:
     16        * fileapi/FileReaderLoaderClient.h:
     17
    1182022-01-24  Youenn Fablet  <youenn@apple.com>
    219
  • trunk/Source/WebCore/fileapi/Blob.cpp

    r284971 r288463  
    242242    public:
    243243        BlobStreamSource(ScriptExecutionContext& scriptExecutionContext, Blob& blob)
    244             : m_loader(makeUniqueRef<FileReaderLoader>(FileReaderLoader::ReadType::ReadAsArrayBuffer, this))
     244            : m_loader(makeUniqueRef<FileReaderLoader>(FileReaderLoader::ReadType::ReadAsBinaryChunks, this))
    245245        {
    246246            m_loader->start(&scriptExecutionContext, blob);
     
    266266        // FileReaderLoaderClient
    267267        void didStartLoading() final { }
    268         void didReceiveData() final
    269         {
    270             auto result = m_loader->arrayBufferResult();
    271             if (!result)
    272                 return;
    273 
    274             if (m_loader->isCompleted() && !m_bytesRead)
    275                 controller().enqueue(WTFMove(result));
    276             else {
    277                 auto bytesLoaded = m_loader->bytesLoaded();
    278                 controller().enqueue(result->slice(m_bytesRead, bytesLoaded));
    279                 m_bytesRead = bytesLoaded;
    280             }
     268        void didReceiveData() final { }
     269        void didReceiveBinaryChunk(const SharedBuffer& buffer) final
     270        {
     271            if (!controller().enqueue(buffer.tryCreateArrayBuffer()))
     272                doCancel();
    281273        }
    282274        void didFinishLoading() final
     
    295287
    296288        UniqueRef<FileReaderLoader> m_loader;
    297         size_t m_bytesRead { 0 };
    298289        bool m_isStarted { false };
    299290        std::optional<Exception> m_exception;
  • trunk/Source/WebCore/fileapi/FileReaderLoader.cpp

    r288088 r288463  
    178178        return;
    179179
     180    if (m_readType == ReadType::ReadAsBinaryChunks) {
     181        if (m_client)
     182            m_client->didReceiveBinaryChunk(buffer);
     183        return;
     184    }
     185
    180186    int length = buffer.size();
    181187    unsigned remainingBufferSpace = m_totalBytes - m_bytesLoaded;
     
    312318            convertToDataURL();
    313319        break;
    314     default:
     320    case ReadAsBlob:
     321    case ReadAsBinaryChunks:
    315322        ASSERT_NOT_REACHED();
    316323    }
  • trunk/Source/WebCore/fileapi/FileReaderLoader.h

    r288088 r288463  
    5959        ReadAsBlob,
    6060        ReadAsText,
    61         ReadAsDataURL
     61        ReadAsDataURL,
     62        ReadAsBinaryChunks
    6263    };
    6364
  • trunk/Source/WebCore/fileapi/FileReaderLoaderClient.h

    r268228 r288463  
    4242    virtual void didStartLoading() = 0;
    4343    virtual void didReceiveData() = 0;
     44    virtual void didReceiveBinaryChunk(const SharedBuffer&) { }
    4445    virtual void didFinishLoading() = 0;
    4546    virtual void didFail(ExceptionCode errorCode) = 0;
Note: See TracChangeset for help on using the changeset viewer.