0
0
Lập trình
Admin Team
Admin Teamtechmely

Tại sao Set.has() vượt trội hơn Array.includes() trong tìm kiếm nhanh chóng với JavaScript

Đăng vào 4 tuần trước

• 4 phút đọc

Chủ đề:

Javascript

Tại sao Set.has() vượt trội hơn Array.includes() trong tìm kiếm nhanh chóng với JavaScript

Trong JavaScript, việc kiểm tra xem một giá trị có tồn tại trong tập hợp dữ liệu hay không là thao tác rất phổ biến. Trong bối cảnh hiệu suất là yếu tố quan trọng, phương thức Set.has() đã trở thành lựa chọn ưu việt hơn so với Array.includes(), đặc biệt là khi làm việc với các tập dữ liệu lớn.

Hiểu rõ về Array.includes() và Set.has()

Trước tiên, hãy tìm hiểu về hai phương thức này cùng với cách hoạt động của chúng trong bối cảnh kiểm tra sự tồn tại của giá trị trong mảng và tập hợp.

1. Phương thức Array.includes()

Phương thức includes() được sử dụng để kiểm tra xem một giá trị có tồn tại trong mảng hay không. Tuy nhiên, nó sử dụng độ phức tạp thời gian là O(n), có nghĩa là thời gian kiểm tra sẽ tỉ lệ thuận với kích thước của mảng. Điều này xảy ra do Array.includes() thực hiện tìm kiếm theo thứ tự từ đầu đến cuối mảng, nên thời gian kiểm tra sẽ kéo dài khi số lượng phần tử trong mảng tăng.

2. Phương thức Set.has()

Ngược lại, phương thức has() của đối tượng Set cũng kiểm tra sự tồn tại của một giá trị nhưng thực hiện điều này hiệu quả hơn nhiều. Với độ phức tạp thời gian O(1), Set.has() cho phép tra cứu ngay lập tức mà không phụ thuộc vào số lượng phần tử trong tập hợp. Điều này là nhờ vào cấu trúc bảng băm, giúp tăng tốc độ tra cứu đáng kể.

Ưu điểm của Set.has() trong việc kiểm tra dữ liệu lớn

Khi sử dụng Set.has(), JavaScript có thể xác định nhanh chóng xem một giá trị có tồn tại hay không chỉ với một thao tác mà không quan tâm đến số lượng phần tử trong tập hợp. Ví dụ, thời gian để kiểm tra một giá trị trong một tập hợp có một triệu phần tử cũng giống như khi kiểm tra trong một tập hợp có mười phần tử.

Ngược lại, Array.includes() thực hiện kiểm tra từng phần tử từ trái sang phải, vì vậy, thời gian kiểm tra sẽ kéo dài đáng kể khi kích thước của mảng lớn, đặc biệt khi giá trị cần tìm không có trong mảng. Dưới đây là một ví dụ cụ thể để minh họa:

javascript Copy
const largeArray = Array.from({ length: 1000000 }, (_, i) => i);
const largeSet = new Set(largeArray);

const valueToFind = 999999;

// Kiểm tra thời gian với Array.includes (O(n))
console.time("Array.includes");
largeArray.includes(valueToFind);
console.timeEnd("Array.includes");

// Kiểm tra thời gian với Set.has (O(1))
console.time("Set.has");
largeSet.has(valueToFind);
console.timeEnd("Set.has");

Khi thực hiện đoạn mã trên, bạn sẽ thấy rằng Set.has() hoạt động nhanh hơn đáng kể so với Array.includes() khi xử lý các mảng lớn. Điều này không chỉ cải thiện độ mượt mà của ứng dụng mà còn giảm thời gian tải và tiết kiệm tài nguyên máy chủ.

Nên sử dụng Set.has() hay Array.includes()?

Việc lựa chọn giữa Set.has() và Array.includes() phụ thuộc vào bối cảnh và yêu cầu cụ thể của ứng dụng. Dưới đây là những lưu ý:

Nên sử dụng Set.has() nếu:

  • Bạn đang làm việc với các tập dữ liệu lớn và cần thực hiện nhiều lần tìm kiếm liên tiếp.
  • Các giá trị của bạn là duy nhất, ví dụ như ID người dùng hoặc từ khóa.
  • Bạn sẵn sàng chấp nhận chi phí hiệu suất thấp để chuyển đổi từ mảng sang set ban đầu giúp tiết kiệm thời gian tra cứu sau này.

Nên sử dụng Array.includes() nếu:

  • Tập dữ liệu của bạn nhỏ, ở mức mà sự khác biệt hiệu suất không đáng kể.
  • Bạn chỉ cần kiểm tra một hoặc vài giá trị mà không cần phải tạo set.
  • Bạn cần xử lý các bản sao của giá trị, vì Set không lưu trữ giá trị trùng lặp.

Ví dụ ứng dụng thực tiễn

Giả sử bạn đang xây dựng chức năng tìm kiếm người dùng và cần lọc tên dựa trên danh sách các từ cấm. Với hàng trăm từ bị chặn, việc sử dụng Set để quản lý các từ cấm sẽ giúp tăng tốc độ kiểm tra mỗi lần tìm kiếm:

javascript Copy
const blockedWords = new Set(["spam", "test", "fakeuser", "bot"]);
const username = "fakeuser42";

if (blockedWords.has(username)) {
  console.log("Tên người dùng bị chặn");
} else {
  console.log("Tên người dùng được cho phép");
}

Ngay cả khi số lượng từ bị chặn nhỏ, việc sử dụng Set vẫn giúp ích cho hiệu suất và khả năng mở rộng ứng dụng trong tương lai.

Những điểm quan trọng cần nhớ

  • Hiệu suất: Set.has() vượt trội với độ phức tạp thời gian O(1) so với Array.includes() với O(n) khi xử lý tập dữ liệu lớn.
  • Tính phù hợp: Set được tối ưu hóa cho các giá trị duy nhất, trong khi mảng có thể chứa các giá trị trùng lặp nhưng tốn thời gian hơn trong việc kiểm tra sự tồn tại.
  • Khả năng mở rộng: Khi dữ liệu tăng lên, Set.has() vẫn hoạt động hiệu quả, trong khi Array.includes() có thể chậm lại.

Kết luận

Việc lựa chọn giữa Set.has() và Array.includes() phụ thuộc vào kích thước và đặc tính của tập dữ liệu. Đối với tập dữ liệu nhỏ, Array.includes() có thể đủ nhưng Set.has() sẽ trở thành công cụ hiệu quả trong các tình huống yêu cầu tốc độ. Cấu trúc dữ liệu phù hợp sẽ giúp tối ưu hóa hiệu suất ứng dụng JavaScript của bạn mà không cần thay đổi mã nguồn nhiều.

Hãy luôn đặt câu hỏi khi bạn cần kiểm tra sự tồn tại của một giá trị: Có phải sử dụng mảng hay nên tận dụng sức mạnh của một set? Lựa chọn đúng đắn có thể mang lại sự khác biệt lớn cho hiệu suất của ứng dụng của bạn.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào