2011-07-01 35 views
5

Có thể ai đó giải thích điều này một với tôi:chuỗi Javascript tốc độ nối

http://jsperf.com/string-concatenation-1/2

Nếu bạn lười biếng, tôi thử nghiệm A) vs B):

Một)

var innerHTML = ""; 

items.forEach(function(item) { 
    innerHTML += item; 
}); 

B)

var innerHTML = items.join(""); 

Trường hợp items cho cả hai bài kiểm tra là cùng một chuỗi 500 phần tử của chuỗi, với mỗi chuỗi là ngẫu nhiên và có độ dài từ 100 đến 400 ký tự.

A) kết thúc nhanh hơn 10x. Làm thế nào điều này có thể được - Tôi luôn luôn nghĩ ghép nối bằng cách sử dụng join("") là một mẹo tối ưu hóa. Có điều gì thiếu sót với các bài kiểm tra của tôi không?

+0

Trừ khi bạn đang tham gia rất nhiều chuỗi (rất lớn phụ thuộc vào trình duyệt), 'Array.Join' chậm hơn' + ' – Mrchief

Trả lời

8

Sử dụng join("") là mẹo tối ưu hóa để soạn chuỗi lớn trên IE6 để tránh O(n**2) bản sao đệm. Nó không bao giờ được dự kiến ​​sẽ là một chiến thắng hiệu suất rất lớn để soạn chuỗi nhỏ kể từ khi O(n**2) chỉ thực sự thống trị chi phí của một mảng cho n lớn.

Trình thông dịch hiện đại xoay quanh điều này bằng cách sử dụng "chuỗi phụ thuộc". Xem điều này mozilla bug để có giải thích về các chuỗi phụ thuộc và một số ưu điểm và nhược điểm.

Về cơ bản, phiên dịch hiện đại biết về một số loại khác nhau của chuỗi:

  1. Một mảng ký tự
  2. Một lát (chuỗi con) của chuỗi khác
  3. Một nối của hai chuỗi khác

Điều này làm cho nối và chuỗi con O (1) với chi phí đôi khi giữ quá nhiều bộ đệm chuỗi con còn sống dẫn đến sự kém hiệu quả hoặc phức tạp trong garbag e collector.

Một số phiên dịch hiện đại đã chơi xung quanh với ý tưởng phân tích thêm (1) thành byte [] s cho chuỗi chỉ ASCII và mảng uint16 khi chuỗi chứa đơn vị mã UTF-16 không thể vừa với byte. Nhưng tôi không biết ý tưởng đó có thực sự ở bất kỳ thông dịch viên nào không.

1

Đây là tác giả của ngôn ngữ lập trình Lua explains the buffer overhead mà @Mike Samuel đang nói đến. Các ví dụ là trong Lua, nhưng vấn đề là như nhau trong JavaScript.