Tóm Tắt Ngắn Gọn:
- Phương thức Array.splice() trong JavaScript có độ phức tạp thời gian là O(n) khi xóa phần tử.
- JavaScript sử dụng inline caching cho các đối tượng động để tăng tốc độ truy cập.
- HiddenClass giúp ghi nhớ thứ tự các thuộc tính, từ đó cho phép sử dụng inline caching hiệu quả cho Objects.
- Do array có thứ tự, HiddenClass không thể áp dụng, dẫn đến việc hoạt động không tối ưu khi có chỉ số trống.
- Để duy trì hiệu năng khi xử lý mảng lớn, chúng ta nên cân nhắc việc sử dụng các cấu trúc dữ liệu khác như Set hoặc Objects.
Giới Thiệu
Trong quá trình làm việc với JavaScript, một trong những phương thức thường được sử dụng để thay đổi nội dung của mảng là Array.splice(). Tuy nhiên, khi số lượng phần tử trong mảng tăng lên đến hàng chục nghìn, việc sử dụng phương thức này có thể gặp phải một số vấn đề về hiệu suất. Điều này đặc biệt quan trọng khi khả năng mở rộng của ứng dụng bạn phụ thuộc vào hiệu suất của các thao tác trên mảng lớn.
Hiệu Năng Của Array.splice()
Một hôm, tôi nhận được lời khuyên từ một lập trình viên kinh nghiệm rằng việc sử dụng Set sẽ nhanh hơn so với Array khi xử lý trạng thái trong React. Để kiểm chứng, tôi đã thử nghiệm với một vài thao tác khác nhau trên mảng, với số lượng phần tử lên đến 1 triệu. Trong quá trình thử nghiệm, tôi nhận thấy rằng:
- Array.splice() chậm hơn nhiều so với Set.delete(), có thể chậm hơn tới 22,000 lần trong một số trường hợp.
- Điều này là do khi thực hiện xóa các phần tử, Array.splice() không chỉ làm mất phần tử mà còn phải thay đổi thứ tự các phần tử còn lại, dẫn đến việc tốn thêm thời gian cho việc chuyển đổi thứ tự.
Cách duy nhất để cải thiện hiệu suất trong các trường hợp này là thay vì xóa một phần tử, chúng ta có thể thay thế nó với một giá trị khác, chẳng hạn như false để làm giá trị placeholder.
Tại Sao Điều Này Xảy Ra?
Có rất nhiều lý do góp phần vào hiệu suất yếu của Array.splice() trong JavaScript, một trong số đó là sự thay đổi của HiddenClass và inline caching. Dưới đây là một vài khái niệm giúp làm rõ:
HiddenClass
HiddenClass là một cơ chế cho phép JavaScript ghi nhận sự thay đổi trong thuộc tính của đối tượng. Mỗi khi một thuộc tính được thêm, thay đổi hoặc xóa, HiddenClass sẽ phân nhánh để tạo ra một chuỗi các class ẩn, điều này giúp JavaScript có thể truy cập thuộc tính một cách nhanh chóng mà không cần phải tìm kiếm lại.
Inline Caching
JavaScript cần inline caching để tối ưu hóa việc truy cập vào các thuộc tính của đối tượng động. Khi thuộc tính của một đối tượng được truy cập nhiều lần, V8 engine sẽ ghi nhớ vị trí của nó, giúp tăng tốc độ truy cập trong tương lai. Tuy nhiên, khi có nhiều thay đổi, hệ thống này có thể bị chậm lại do việc phải tìm kiếm lại liên tục.
Sự Khác Biệt Giữa Array và Objects
Các mảng (Array) không sử dụng HiddenClass như Objects, vì chúng có cấu trúc và cách truy cập khác nhau. Array có thể chứa các chỉ số trống, và JavaScript sử dụng một giá trị đặc biệt để quản lý các chỉ số này. Do đó, việc xử lý mảng sẽ trở nên kém hiệu quả khi có nhiều hoạt động thay đổi hoặc xóa.
Kết Luận
Với những nhận thức trên, tôi hi vọng bài viết này sẽ giúp bạn hiểu rõ hơn về cách sử dụng Array.splice() trong JavaScript và những tác động của nó đến hiệu suất. Hãy xem xét việc tối ưu hóa mã nguồn của bạn khi làm việc với các mảng lớn, và đừng quên những lựa chọn thay thế như Set hoặc Object để đạt hiệu suất tốt nhất trong ứng dụng của bạn.
Cảm ơn bạn đã đọc!