Tìm hiểu về Copy on Write trong Swift

by cuongpt
276 views

Copy on Write (CoW) là 1 khái niệm ko hề mới trong Swift. Nó đã được Apple giới thiệu trong WWDC 2015 và được áp dụng từ iOS 7.0. Tuy nhiên thực chất CoW là gì và chúng có tác dụng gì? Hãy cùng tìm hiểu trong bài viết này nhé.

Table of contents

  • Copy on Write là gì
  • Kết luận
  • References

Copy on Write là gì?

  • Trong Swift, chúng ta có các kiểu Reference type và Value type. 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 parameter kiểu inout) thì dữ liệu của value type này sẽ được copy. Lúc này, ta sẽ có hai value type có nội dung giống nhau nhưng trỏ đến hai địa chỉ bộ nhớ riêng biệt. Hôm nay ta sẽ bàn về Copy on Write – một cơ chế quan trọng trong việc tối ưu bộ nhớ của Swift.

  • Trong Swift, khi bạn có một khối lượng lớn các value type và muốn gán hoặc truyền chúng qua các function, nếu bạn copy tất cả dữ liệu sang một vị trí khác trong bộ nhớ thì sẽ gây ra hiện tượng lãng phí hiệu năng. Để giảm thiểu tình trạng này, Swift đã triển khai cơ chế Copy on Write cho một số kiểu dữ liệu là value type như array, dictionary,…

  • Hiểu 1 cách đơn giản, nếu bạn có 1 array có 1000 phần tử và bạn muốn copy mảng đó vào 1 biến khác, Swift sẽ không sao chép ngay lập tức cả 1000 phần tử này mà sẽ sử dụng đến cơ chế Copy on Write: Khi bạn trỏ 2 biến vào cùng 1 mảng, chúng đều trỏ vào cùng 1 địa chỉ ô nhớ, và chỉ đến khi bạn sửa đổi 1 trong 2 biến đó, swift mới tạo ra 1 bản copy mới để sửa và chỉ sửa trên bản copy đó và vẫn giữ nguyên biến còn lại. Bằng cách trì hoãn việc sao chép dữ liệu cho đến khi thực sự cần thiết, Swift đã đảm bảo được việc tối ưu được performance của hệ thống

  • Copy on Write ko phải là cơ chế mặc định cho tất cả các kiểu value type, mà chỉ được áp dụng cho 1 số kiểu như Aray, Collections,… Ngoài ra, với những kiểu value type mà bạn tự custom thì cũng ko có sẵn cơ chế này mà phải tự implement thêm.

  • Ví dụ về cách hoạt động của Copy on Write

import Foundation

func print(address o: UnsafeRawPointer ) {
    print(String(format: "%p", Int(bitPattern: o)))
}

var array1: [Int] = [0, 1, 2, 3]
var array2 = array1

//Print with just assign
print(address: array1) //0x600000078de0
print(address: array2) //0x600000078de0
//Let's mutate array2 to see what's
array2.append(4)

print(address: array2) //0x6000000aa100

//Output
//0x600000078de0 array1 address
//0x600000078de0 array2 address before mutation
//0x6000000aa100 array2 address after mutation

Đây là 1 ví dụ đơn giản để chỉ cách hoạt động của Copy on Write. Trước hết, tạo biến array1 rồi sau đó gán aray2 bằng với array1. Khi chưa thực hiện thay đổi giá trị thì array2 vẫn trỏ vào cùng 1 địa chỉ ô nhớ với array1. Chỉ khi ta thay đổi giá trị của array2 thì nó mới được copy sang 1 địa chỉ ô nhớ khác, và giá trị mới sẽ trỏ vào địa chỉ ô nhớ này, còn array1 sẽ không có sự thay đổi gì.

Implement cơ chế Copy on Write cho các dạng value type tự tạo

  • Bạn có thể tự mình implement cơ chế Copy on Write cho các kiểu dữ liệu mà bạn tự custom. Đây là ví dụ trên OptimizationTips.rst trong repo chính của Swift
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

Đoạn code trên sử dụng loại reference type để triển khai cho kiểu giá trị dạng generics. Về cơ bản, đây là 1 warrper quản lý loại reference type và chỉ trả về 1 instance mới nếu giá trị được tham chiếu không là duy nhất. Nếu không, nó chỉ thay đổi giá trị của kiểu tham chiếu.

Kết luận:

Copy on Write là 1 cơ chế rất thông minh để tối ưu hoá việc copy giá trị của các kiểu value type. Đây là 1 cơ chế được sử dụng rất nhiều Swift, dù hầu như chúng ta ko nhìn thấy nó 1 cách rõ ràng vì chúng đã được thực hiện trên các thư viện chuẩn của Swift. Nhưng chúng ta nên biết để có thể tận dụng tối đa lợi ích mà Copy on Write mang lại.

Refer:

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

You may also like