Gần đây tôi gặp vấn đề với một mảng chứa hàng trăm nghìn giá trị và điều duy nhất tôi muốn làm là kiểm tra xem liệu giá trị đã có mặt chưa. Trong trường hợp của tôi, đây là các IP từ nhật ký máy chủ web. Vì vậy, về cơ bản giống như:Có cấu trúc dữ liệu thay thế nào so với mảng trong PHP, nơi tôi có thể hưởng lợi từ các kỹ thuật chỉ mục khác nhau không?
in_array(ip2long(ip),$myarray)
đã làm công việc
Tuy nhiên, thời gian tra cứu tăng lên đáng kể và 10k của tra cứu mất khoảng 17 giây hoặc lâu hơn.
Vì vậy, trong trường hợp này tôi không quan tâm liệu tôi có sao chép hay không, tôi chỉ cần kiểm tra sự tồn tại. Vì vậy, tôi có thể lưu trữ các IP trong chỉ mục như thế này:
isset($myarray[ip2long($ip)])
Và thời gian tra cứu giảm xuống từ 17 giây (và nhiều hơn nữa) đến thời gian tĩnh 0,8 giây cho tra cứu 10k. Là một giá trị cho mục nhập mảng, tôi chỉ sử dụng int 1
.
Tôi nghĩ rằng chỉ mục mảng có thể dựa trên một số b-tree cần có thời gian tra cứu nhật ký (n) và chỉ mục trên băm.
Trong trường hợp của tôi bằng cách sử dụng chỉ mục hoạt động tốt, nhưng có bất kỳ cấu trúc dữ liệu nào mà tôi có thể sử dụng hashmaps như một chỉ mục giá trị, trong đó nhiều giá trị cũng có thể xảy ra (tôi nhận thấy rằng điều này chỉ có ý nghĩa nếu không có quá nhiều bản sao và tôi không thể sử dụng yêu cầu phạm vi/tìm kiếm hiệu quả, đó là lợi ích chính của cấu trúc cây)?
Đôi khi giải pháp tốt nằm ngay trước mặt bạn và bạn chỉ nghĩ quá phức tạp. - Tuyệt vời. – Smamatti
Ông lật nó từ những gì tôi hiểu. –
Sử dụng isset ($ a [$ key]) là nhiều (!) Nhanh hơn array_key_exists ($ key, $ a), bởi vì isset là một cấu trúc và array_key_exists() là một hàm. – BurninLeo