Hy vọng hai chiều indexOf
/ lastIndexOf
thay thế nhanh hơn
2015
Mặc dù phương thức mới bao gồm rất hay, nhưng về cơ bản thì sự hỗ trợ là bằng không.
Lâu lắm rồi tôi mới nghĩ ra cách thay thế các hàm indexOf / lastIndexOf chậm.
Một cách biểu diễn đã được tìm thấy, nhìn vào các câu trả lời hàng đầu. Từ những người tôi đã chọn contains
chức năng được đăng bởi @Damir Zekic, đây là chức năng nhanh nhất. Nhưng nó cũng nói rằng các điểm chuẩn là từ năm 2008 và do đó đã lỗi thời.
Tôi cũng thích while
hơn for
, nhưng không phải là một lý do cụ thể, tôi đã kết thúc việc viết hàm với một vòng lặp for. Nó cũng có thể được thực hiện với mộtwhile --
.
Tôi đã tò mò nếu việc lặp lại chậm hơn nhiều nếu tôi kiểm tra cả hai mặt của mảng trong khi thực hiện nó. Rõ ràng là không, và do đó, chức năng này nhanh hơn khoảng hai lần so với các chức năng được bình chọn hàng đầu. Rõ ràng nó cũng nhanh hơn bản địa. Điều này trong một môi trường thế giới thực, nơi bạn không bao giờ biết liệu giá trị bạn đang tìm kiếm là ở đầu hay cuối mảng.
Khi bạn biết rằng bạn vừa đẩy một mảng có giá trị, sử dụng lastIndexOf có thể vẫn là giải pháp tốt nhất, nhưng nếu bạn phải đi qua các mảng lớn và kết quả có thể ở khắp mọi nơi, đây có thể là một giải pháp vững chắc để làm mọi thứ nhanh hơn.
Chỉ mục hai chiềuOf / last IndexOf
function bidirectionalIndexOf(a, b, c, d, e){
for(c=a.length,d=c*1; c--; ){
if(a[c]==b) return c; //or this[c]===b
if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
}
return -1
}
//Usage
bidirectionalIndexOf(array,'value');
Kiểm tra hiệu suất
http://jsperf.com/bidirectionalindexof
Khi kiểm tra tôi đã tạo ra một mảng với 100k mục.
Ba truy vấn: ở đầu, ở giữa & ở cuối mảng.
Tôi hy vọng bạn cũng tìm thấy điều này thú vị và kiểm tra hiệu suất.
Lưu ý: Như bạn có thể thấy tôi đã sửa đổi một chút contains
chức năng để phản ánh đầu ra indexOf & lastIndexOf (về cơ bản là true
với index
và false
với -1
). Điều đó không nên làm hại nó.
Các biến thể nguyên mẫu mảng
Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
for(c=this.length,d=c*1; c--; ){
if(this[c]==b) return c; //or this[c]===b
if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
}
return -1
},writable:false, enumerable:false});
// Usage
array.bidirectionalIndexOf('value');
Hàm này cũng có thể dễ dàng được sửa đổi để trả về true hoặc false hoặc thậm chí là đối tượng, chuỗi hoặc bất cứ thứ gì.
Và đây là while
biến thể:
function bidirectionalIndexOf(a, b, c, d){
c=a.length; d=c-1;
while(c--){
if(b===a[c]) return c;
if(b===a[d-c]) return d-c;
}
return c
}
// Usage
bidirectionalIndexOf(array,'value');
Sao có thể như thế được?
Tôi nghĩ rằng phép tính đơn giản để lấy chỉ số phản ánh trong một mảng đơn giản đến mức nhanh hơn hai lần so với thực hiện một vòng lặp thực tế.
Dưới đây là một ví dụ phức tạp khi thực hiện ba kiểm tra mỗi lần lặp, nhưng điều này chỉ có thể với một phép tính dài hơn gây ra sự chậm lại của mã.
http://jsperf.com/bidirectionalindexof/2