2012-02-10 28 views
18

Sự khác biệt giữa javascript ArrayObject không phải là rất lớn. Trong thực tế có vẻ như Array chủ yếu là bổ sung thêm lĩnh vực length, vì vậy bạn có thể sử dụng cả hai Array s và Object s như mảng số:Mảng javascript có thực sự được triển khai dưới dạng mảng không?

var ar = new Array(); 
ar[0] = "foo"; 
ar["bar"] = "foo"; 

var ob = new Object(); 
ob[0] = "foo"; 
ob["bar"] = "foo"; 

assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true. 

Vì vậy, câu hỏi của tôi là, trong công cụ javascript phổ biến (V8, JavaScriptCore, SpiderMonkey, vv), cách xử lý này? Rõ ràng chúng tôi không muốn mảng của chúng tôi được lưu trữ dưới dạng bản đồ băm với các giá trị chính! Làm thế nào chúng ta có thể chắc chắn rằng dữ liệu của chúng tôi được lưu trữ như một mảng thực tế?

Theo như tôi có thể thấy có một vài phương pháp tiếp cận cơ có thể mất:

  1. Array được thực hiện chính xác theo cùng một cách như Object - như một mảng kết hợp với các phím chuỗi.
  2. Array là một trường hợp đặc biệt, với một mảng -like std::vector ủng hộ các phím số, và một số heuristic, mật độ để ngăn chặn sử dụng bộ nhớ điên nếu bạn làm ar[100000000] = 0;
  3. Array cũng giống như Object, và tất cả các đối tượng có được một heuristic để xem nếu sử dụng một mảng sẽ có ý nghĩa hơn.
  4. Điều gì đó cực kỳ phức tạp mà tôi chưa từng nghĩ đến.

Thực sự điều này sẽ đơn giản hơn nếu có một loại mảng thích hợp (ho WebGL gõ mảng ho).

+2

Bài viết này (http://news.qooxdoo.org/javascript-array-performance-oddities-characteristics) hơi cũ và không giải thích rõ ràng việc triển khai. Tuy nhiên, nó thực hiện các phép đo hiệu suất chi tiết và đưa ra các triển khai có khả năng. –

+2

Array không phải là _just_ một bản đồ có thuộc tính 'length' được gắn vào. Nếu đúng như vậy, thì việc dịch chuyển hoặc unshifting sẽ phá vỡ việc lập chỉ mục (tức làchuyển một giá trị ra khỏi mảng, và nó vẫn bắt đầu ở chỉ số 0, không phải 1). Vì vậy, có ít nhất một chút nữa. (Không phải điều này nhất thiết phải nói bất cứ điều gì về việc thực hiện, tất nhiên) – Flambino

+1

Tại sao bạn mong đợi 'r [0] == ob [0] == ar [" 0 "] == ob [" 0 "] == ar. bar == ob.bar' là đúng? ''a' == 'a' == 'a'' là sai bởi vì nó đánh giá thành' true ==' a'' để đánh giá thành 'false'. –

Trả lời

12

Trong SpiderMonkey, mảng được triển khai cơ bản là mảng C của các khoảng thời gian. Chúng được gọi là "mảng dày đặc". Tuy nhiên, nếu bạn bắt đầu làm những thứ giống như mảng với chúng - giống như đối xử với chúng như các đối tượng - việc thực hiện chúng được thay đổi thành một thứ rất giống với các đối tượng.

Đạo đức của câu chuyện: khi bạn muốn một mảng, hãy sử dụng mảng. Khi bạn muốn một đối tượng, hãy sử dụng một đối tượng.

Ồ, một jsval là một loại kiểu variadic có thể đại diện cho bất kỳ giá trị JavaScript có thể có nào trong loại C 64 bit.

6

Trong V8 và Carakan (và có lẽ là Chakra), tất cả (không phải là máy chủ) đối tượng (cả hai là mảng và không) với thuộc tính có tên là chỉ mục mảng (như được định nghĩa trong ES5) được lưu trữ dưới dạng hoặc một mảng dày đặc (một mảng C chứa một số giá trị wrapper) hoặc một mảng thưa thớt (được thực hiện như là một cây tìm kiếm nhị phân).

Biểu diễn đối tượng hợp nhất thể hiện qua đó nó ảnh hưởng đến thứ tự liệt kê: với một đối tượng, SpiderMonkey và SquirrelFish đều cung cấp tất cả các thuộc tính trong thứ tự chèn; và với một mảng, chúng nói chung (có những trường hợp đặc biệt trong SM ít nhất!) các chỉ mục mảng đầu tiên sau đó tất cả các thuộc tính khác trong thứ tự chèn. V8, Carakan, và Chakra luôn cung cấp cho các chỉ mục mảng đầu tiên sau đó tất cả các thuộc tính khác trong thứ tự chèn, bất kể loại đối tượng.

Các vấn đề liên quan