Hiểu về Copy-on-Write trong Swift

Đăng bởi: Admin | Lượt xem: 1360 | Chuyên mục: Swift

Trong Swift, ta có kiểu reference type (Class) và value type (Struct, Tuble, enum). Kiểu value type có bản chất là copy. Có nghĩa là nếu bạn gán một value type cho một biến hoặc pass nó như một parame...


Trong Swift, ta có kiểu reference type (Class) và value type (Struct, Tuble, enum). Kiểu value type có bản chất là copy. Có nghĩa là nếu bạn gán một value type cho một biến hoặc pass nó như một parameter của function (không phải inout), dữ liệu của value type này sẽ được copy. Lúc này, bạn sẽ có 2 value type có nội dung giống nhau nhưng có 2 địa chỉ bộ nhớ riêng biệt. Hôm nay chúng ta sẽ nói về Copy-on-Write (CoW), một thứ rất quan trọng để hiểu về cách quản lý bộ nhớ value type của Swift

Copy-on-Write là gì?

Trong Swift, khi bạn có một lượng lớn các value type và gán hoặc truyền chúng qua các function, việc copy rất tốn kém về mặt hiệu năng vì bạn sẽ phải copy tất cả dữ liệu sang một vị trí khác trong bộ nhớ. Để giảm thiểu vấn đề này, thư viện chuẩn của Swift đã cài đặt một cơ chế cho một số loại value type như Array, khi mà giá trị chỉ được copy khi chúng bị thay đổi, thậm chí là chỉ khi có hơn một tham chiếu đến nó (bởi nếu giá trị có một tham chiếu duy nhất, nó không cần phải copy nữa, khi đó, nó chỉ cần thay đổi trên tham chiếu thôi). Khi đó, nếu chỉ gán hoặc truyền một Array qua function, sẽ không cần phải copy và sẽ cải thiện được hiệu năng

Một lưu ý quan trọng là …

Copy-on-Write không phải là cách làm việc mặc định của value type, nó chỉ được cài đặt cho một số loại dữ liệu cụ thể trong Swift Standard Library như Array và Collection mà thôi. Điều này có nghĩa là không phải mọi value type trong Swift Standard Library điều có CoW. Đương nhiên là các value type bạn tự tạo cũng sẽ không có nó, trừ khi bạn tự mình cài đặt chúng (sẽ được đề cập ở phần sau)

Giờ hãy xem nó hoạt động thế nào qua ví dụ sau: 

Đây là cách đơn giản cho thấy cách mà Copy-on-Write hoạt động. Khởi tạo array1 với giá trị, sau đó gán cho array2. Khi đó, khi array2 chưa có sự thay đổi, ta có thể thấy nó chưa hề được copy, địa chỉ của array2 vẫn giống với array1. Sau khi thay đổi array2, ta thấy địa chỉ của nó đã bị thay đổi.

Cài đặt Copy-on-Write cho custom value type

Bạn có thể tự cài đặt CoW cho value type của mình. Ví dụ dưới đây có thể tìm thấy ở OptimizationTips.rst của Swift main repo.

final class Ref<T> {
  var val : T
  init(_ v : T) {val = v}
}

struct Box<T> {
    var ref : Ref<T>
    init(_ x : T) { ref = Ref(x) }

    var value: T {
        get { return ref.val }
        set {
          if (!isUniquelyReferencedNonObjC(&ref)) {
            ref = Ref(newValue)
            return
          }
          ref.val = newValue
        }
    }
}
// This code was an example taken from the swift repo doc file OptimizationTips 
// Link: https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-use-copy-on-write-semantics-for-large-values

Đây là đoạn code mới chỉ ra cách dùng một reference type để cài đặt CoW cho một value type T bất kỳ. Về cơ bản, đây là một wrapper quản lý reference type và chỉ trả về một instance mới khi giá trị không có tham chiếu độc nhất. Mặt khác, nó chỉ thay đổi giá trị của reference type

Kết luận

Copy-on-Write là một phương pháp thông minh để tối ưu việc copy của value type và là một cơ chế được dùng rất nhiều trong Swift, cho dù chúng ta hầu như không thể nhìn thấy nó vì nó đã được cài đặt trong Standard Library. Nhưng chắc chắn vẫn tốt khi ta có thể biết và có thể áp dụng nó vào code hàng ngày để nâng cao được hiệu năng của ứng dụng.

vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!


Được xem nhiều nhất

Chuyên mục: Swift



Hiểu về Copy-on-Write trong Swift
14/05/2020 | Lượt xem: 1360

Tìm hiểu về Properties trong Swift
14/05/2020 | Lượt xem: 1276

Khóa học liên quan

Khóa học: Swift

Lập trình Swift cơ bản
Số bài học:
Lượt xem: 19477
Đăng bởi: Admin
Chuyên mục: Swift