@@ -262,16 +262,30 @@ final class Downloader: NSObject, Sendable {
262262
263263 var newNumRetries = numRetries
264264 do {
265+ // Batch collect bytes to reduce Data.append() overhead
266+ // Use ContiguousArray for better performance (no NSArray bridging overhead)
267+ let batchSize = 16384 // 16 kB
268+ var byteBatch = ContiguousArray < UInt8 > ( )
269+ byteBatch. reserveCapacity ( batchSize)
270+
265271 for try await byte in asyncBytes {
266- buffer. append ( byte)
272+ byteBatch. append ( byte)
273+
274+ // Append batch to main buffer
275+ if byteBatch. count >= batchSize {
276+ buffer. append ( contentsOf: byteBatch)
277+ byteBatch. removeAll ( keepingCapacity: true )
278+ }
279+
267280 // When buffer is full, write to disk
268- if buffer. count = = chunkSize {
281+ if buffer. count > = chunkSize {
269282 if !buffer. isEmpty { // Filter out keep-alive chunks
270283 try tempFile. write ( contentsOf: buffer)
284+ let bytesWritten = buffer. count
271285 buffer. removeAll ( keepingCapacity: true )
272286
273- totalDownloadedLocal += chunkSize
274- await downloadResumeState. incDownloadedSize ( chunkSize )
287+ totalDownloadedLocal += bytesWritten
288+ await downloadResumeState. incDownloadedSize ( bytesWritten )
275289 newNumRetries = 5
276290 guard let expectedSize = await downloadResumeState. expectedSize else { continue }
277291 let progress = expectedSize != 0 ? Double ( totalDownloadedLocal) / Double( expectedSize) : 0
@@ -289,6 +303,11 @@ final class Downloader: NSObject, Sendable {
289303 }
290304 }
291305
306+ // Flush remaining bytes from batch
307+ if !byteBatch. isEmpty {
308+ buffer. append ( contentsOf: byteBatch)
309+ }
310+
292311 if !buffer. isEmpty {
293312 try tempFile. write ( contentsOf: buffer)
294313 totalDownloadedLocal += buffer. count
@@ -445,12 +464,8 @@ actor Broadcaster<E: Sendable> {
445464
446465 func broadcast( state: E ) async {
447466 latestState = state
448- await withTaskGroup ( of: Void . self) { group in
449- for continuation in continuations. values {
450- group. addTask {
451- continuation. yield ( state)
452- }
453- }
467+ for continuation in continuations. values {
468+ continuation. yield ( state)
454469 }
455470 }
456471}
0 commit comments