Big O có thực sự quan trọng không?


17

Trong học viện, trường hợp xấu nhất Big O được dạy về mọi thứ khác. So với độ phức tạp không gian, phân tích trường hợp bình thường, đơn giản hơn độ phức tạp, v.v.

Đặc biệt là lập trình trò chơi và công nghiệp, điều gì thực sự quan trọng nhất và tại sao?

Tài liệu tham khảo sẽ rất hữu ích.


Big-O = Tối ưu hóa. Mất một chút để tìm ra big-0 là gì.
Tấn

12
Big-O không phải là "tối ưu hóa". Big-O là một hình thức phân tích cho bạn biết các thuật toán khác nhau sẽ hoạt động như thế nào, về mặt hiệu quả, khi số lượng các yếu tố hành động tăng lên. Xem en.wikipedia.org/wiki/Big_O_notation để biết thêm chi tiết.
ZorbaTHut

2
Tôi có thể đảm bảo với bạn rằng những người đã đưa ra octrees và BSP / PVS biết tất cả về big-O. Cuối cùng, điều duy nhất quan trọng là hiệu năng của ứng dụng. Nhưng để đạt được điều đó, bạn phải xem xét tất cả mọi thứ, bao gồm cả sự phức tạp tiệm cận của các thuật toán xử lý rất nhiều dữ liệu.
drxzcl

1
Hãy nhớ quy tắc khi nào cần tối ưu hóa: 1) Đừng làm điều đó. 2) (chỉ các chuyên gia) Đừng làm điều đó.
zaratustra

Vâng, trước hết Big O có thể được sử dụng cho không gian hoặc độ phức tạp tính toán, vì vậy "trên tất cả mọi thứ khác" không chính xác. Thứ hai, Big O thường đơn giản hơn rất nhiều để tính toán cho một cái gì đó so với phân tích trường hợp thông thường và sẽ được sử dụng như một kiểm tra tinh thần nhanh chóng cho dù bạn đang làm gì sai. Nếu vẽ một sprite mất thời gian O (2 ^ n), có lẽ bạn nên chọn một thuật toán khác. Nếu bạn muốn một cách tiếp cận thực tế hơn để thiết kế phần mềm, hãy nhìn vào thực tiễn SE hơn là CS. CS có bản chất lý thuyết, trong khi SE dựa nhiều vào công nghiệp.
Deleter

Câu trả lời:


25

Như với mọi câu hỏi khác liên quan đến "Đường dẫn thực sự là gì", đây đều là những công cụ trong hộp công cụ của bạn và có những trường hợp big-O vấp ngã mọi thứ và những nơi không quan trọng (tm).

Bạn sẽ "không bao giờ" viết một bộ giải vật lý mà không quan tâm đến big-O. Bạn sẽ không thực hiện thuật toán sắp xếp (cho bất kỳ trừ bộ dữ liệu nhỏ nhất) mà không cần quan tâm đến nó. Nếu bạn đang viết một trò chơi nối mạng, bạn sẽ quan tâm đến cách hiệu suất và quy mô lưu lượng truy cập mạng trên mỗi người dùng.

Bạn có thể không quá quan tâm đến big-O khi, tốt, tôi thực sự không thể nghĩ đến một thời gian nhưng tôi chắc chắn có một số. :) Rất may, hầu hết những điều chúng tôi làm trong các trò chơi có quy mô tuyến tính; Bạn muốn đọc một tập tin ra khỏi đĩa? Sẽ mất một khoảng thời gian tỷ lệ tuyến tính với kích thước tệp (giảm giá yếu tố liên tục tìm kiếm và khả năng phân chia kích thước ngành).

Tuy nhiên, nếu bạn muốn tìm một thực thể cụ thể trong danh sách thực thể thì sao? Đó là một tìm kiếm tuyến tính mỗi khi bạn làm điều đó. Nếu bạn cần tìm người chơi một lần cho mọi thực thể trên thế giới, cách tiếp cận này sẽ giết bạn cho tất cả trừ những trò chơi tầm thường nhất, và thậm chí sau đó có lẽ đáng để "tối ưu hóa" việc tra cứu này là thời gian không đổi (ví dụ: lưu trữ chỉ mục hoặc một con trỏ tới người chơi ở đâu đó), giúp bạn có thêm thời gian để làm những việc khác mà người chơi có thể nhìn thấy.

Tôi đoán rằng tổng hợp nó, mặc dù; bất cứ khi nào bộ xử lý làm điều gì đó không thể biểu thị trực tiếp cho người chơi, điều đó sẽ lãng phí thời gian. Tối đa hóa lượng thời gian mà bộ xử lý đang tính toán dữ liệu sẽ được hiển thị cho người chơi đang tối đa hóa WOW! bạn đang cho người chơi.


8
Điều này. Điều quan trọng là phải hiểu các đặc tính hiệu suất của mã của bạn. Bạn không bao giờ biết khi nào một nhà thiết kế sẽ sử dụng thứ gì đó bạn đã thêm theo cách bạn không mong đợi và đột nhiên, đoạn mã bạn nghĩ sẽ chỉ phải xử lý 5 mục hiện đang xử lý 5000 và được ping 100 lần một khung. Bạn có tối ưu hóa điều đó? Bạn có thể? Có bao nhiêu là thực sự hợp lý? Một hồ sơ sẽ chỉ cho bạn biết nó chậm như thế nào chứ không phải tại sao. Biết được sự phức tạp sẽ cho bạn biết liệu bạn cần tối ưu hóa mã, hoặc thay thế nó bằng một cái gì đó khác biệt.
JasonD

3
Đã đồng ý. Các trường đại học dạy cho bạn 'Big-O' vì nó xử lý nhiều vấn đề bạn sẽ gặp phải. Khi bạn được hỏi 'oh, chúng ta có thể làm điều này vô hạn thay vì chỉ 5? những người thử nghiệm ghét sự giới hạn 'đó là khi việc đào tạo được đền đáp. Bạn không nên chỉ nói 'không tôi không thể'. Điều quan trọng là có thể giải quyết vấn đề từ đó và nói 'vâng tôi có thể'. Trò chơi của bạn cần một thiên hà có thể tìm kiếm? 'Không vấn đề gì'. Những triệu đơn vị cần phải được đặt hàng? 'Không vấn đề gì'. "Không nghiên cứu đủ" chỉ không cắt nó.
Rushyo

"Bạn có thể không quá quan tâm đến big-O khi ..." xử lý các phím nhập. Tôi đã kế thừa một hệ thống đầu vào có độ dài để giải quyết khóa-> ánh xạ hành động trong thời gian không đổi, sử dụng bảng tra cứu. Chuyển nó sang tìm kiếm tuyến tính một mảng các cặp (khóa, hành động) đã lưu bộ nhớ và không có tác động hiệu suất, vì người dùng hiếm khi nhấn nhiều hơn một vài phím trong khung và mảng thường chỉ dài 20-30 mục. Nó cũng cho phép chúng ta thêm (phím, phím, hành động) cho hợp âm.

Joe, chắc chắn, mặc dù đó là một loại mối quan tâm khác. Bạn có muốn O (1) trong đó hệ số không đổi cao hay O (n) với 'n' nhỏ và hệ số không đổi thấp? Biết big-O trong trường hợp này không phải là vấn đề nhưng có thể giúp bạn tìm ra liệu giải pháp đó có hợp lý với hoàn cảnh mà nó sẽ được sử dụng hay không.
dash-tom-bang

13

Nguyên tắc nhỏ của tôi là trừ khi bạn O (đáng sợ), các vấn đề khác của bạn sẽ phù hợp hơn.

Quy tắc khác của tôi là dữ liệu là vua. Trừ khi bạn cấu hình mã của mình bằng một bộ dữ liệu thực tế, bạn chỉ đang đoán.

Chỉnh sửa: Để đi sâu vào chi tiết hơn một chút, chữ O lớn của bạn không quan trọng lắm vì (ít nhất là theo kinh nghiệm của tôi) hầu hết các tập dữ liệu của bạn tương đối nhỏ. Bạn có thể không quan tâm đến giới hạn hiệu suất cao hơn của mình khi bạn làm việc với cấu trúc dữ liệu có ít hơn vài trăm phần tử. Và nếu danh sách của bạn có 100k + phần tử thì bạn thực sự cần phải xem xét tất cả các khía cạnh của thuật toán của mình. Điều đó, và từ kinh nghiệm bộ nhớ của tôi là một yếu tố hạn chế hơn tốc độ CPU. Một thuật toán ăn cắp bộ nhớ nhanh hơn có thể không tốt bằng một thuật toán gọn hơn nhưng chậm hơn tùy thuộc vào các trường hợp sử dụng của bạn.


8

Big O quan trọng hầu hết thời gian, nhưng đôi khi một thuật toán rõ ràng "tệ hơn" trong lý thuyết hóa ra lại nhanh hơn nhiều trong thực tế.

Kiểm tra một ví dụ tuyệt vời từ Tony Albrecht: http://seven-degrees-of-freedom.blogspot.com/2010/07/question-of-sorts.html

Bạn tìm thấy điều này ở khắp mọi nơi trong quá trình phát triển trò chơi trong đó số lượng vật phẩm trong hoạt động quá lớn đến nỗi thuật toán rất khác nhanh hơn hoặc nhỏ đến mức thuật toán giả lập là đủ (hoặc phù hợp với bộ đệm nên nó sẽ ghi đè hiệu quả của thuật toán tốt hơn ).

Vấn đề với Big O là nó chỉ định chung về độ phức tạp của nhiệm vụ và không tính đến độ phức tạp của phần cứng mục tiêu hiện đại, cũng như không cung cấp bất kỳ thông tin chi tiết nào về thời gian thiết lập.

Trong nhiều trường hợp, giải pháp tối ưu tốt nhất là hai bước. Trong thực tế, các nhà phát triển trò chơi có xu hướng hướng tới các thuật toán O thấp nhưng cân bằng với chi phí trong thời gian phát triển hoặc gỡ lỗi. Một khi bạn có một giải pháp hợp lý, bạn luôn phải xem xét cách phần cứng xử lý công việc và làm thế nào để phần cứng được thực hiện nhiều hơn trong thời gian ngắn hơn.


"Vấn đề với Big O" là mọi người dường như quên rằng đó là hiệu suất wrt độ phức tạp thuật toán so với kích thước tập dữ liệu lớn. Trong các trò chơi, chúng tôi không (thường) đạt các giá trị N đó, vì vậy chúng tôi cần quan tâm đến các phần khác của câu đố. Tôi nghi ngờ rằng sắp xếp bong bóng sẽ luôn vượt trội so với quicksort khi bạn có một danh sách gồm hai yếu tố.
dash-tom-bang

7

Khi tôi mã hóa trong động cơ, tôi thường chỉ quan tâm đến việc cố định n: Tôi đã có một phân vùng spacial hạn chế số lượng đối tượng tiếp nhận update(), physics()render()đến khoảng những người trên màn hình và các vùng lân cận. Kích thước lô tối đa thường được xác định khá rõ trên mỗi trò chơi, mặc dù vậy, nó luôn lớn hơn một chút so với kế hoạch của bạn.

Trong trường hợp này, tôi không quan tâm nhiều đến big-O như tôi quan tâm đến hệ số nhân hệ số không đổi và các điều khoản bậc thấp hơn. Đối với một chức năng có thời gian chạy như a*n^2 + b*n + c(đó là O(n^2)), tôi thường quan tâm nhiều hơn đến việc giảm avà có thể loại bỏ c. Chi phí thiết lập hoặc chi phí ccó thể trở nên tương đối lớn so với nhỏ n.

Tuy nhiên, điều này không có nghĩa là big-O (hay đặc biệt hơn là big-theta ) là một chỉ số mùi mã tuyệt vời. Xem một O(n^4)nơi nào đó, hoặc tệ hơn là O(k^n)thời gian hình học, và đó là thời gian để đảm bảo bạn đang xem xét các lựa chọn khác.

Tôi thường quan tâm nhiều hơn đến sự tối ưu của big-O và nhảy qua các vòng để tìm thuật toán với big-O thấp hơn khi tôi làm việc với các công cụ tạo dữ liệu. Mặc dù số lượng đối tượng trong một cấp độ / khu vực phát trực tuyến thường được xác định rõ, nhưng tổng số đối tượng / tài sản nghệ thuật / tệp cấu hình / vv trên toàn bộ trò chơi có thể không được. Đó cũng là một số lượng lớn hơn nhiều. Ngay cả khi chạy một dữ liệu song song, chúng tôi vẫn chờ theo thứ tự một phút (tôi biết, tiếng rên rỉ - dữ liệu tạo ra cho bảng điều khiển có thể mất hàng giờ - chúng tôi chủ yếu là các trò chơi cầm tay nhỏ) để trải qua một jam data-clean && jam datachu kỳ.

Để đưa ra một ví dụ cụ thể: điều này thực sự vượt quá khả năng với thuật toán phát trực tuyến hình nền phát trực tiếp các ô xếp màu 8 x 8. Thật hữu ích khi chia sẻ bộ đệm phát trực tuyến giữa các "lớp" nền và chúng tôi có thể có tới 6 lớp trong một mức nhất định chia sẻ cùng một bộ đệm. Vấn đề là việc ước tính kích thước của bộ đệm cần thiết dựa trên các vị trí có thể có của cả 6 lớp - và nếu chúng là tốc độ cuộn / chiều cao / chiều cao của số nguyên tố, bạn sẽ nhanh chóng bắt đầu tìm kiếm toàn diện - bắt đầu tiếp cậnO(6^numTiles)- trong danh mục "dài hơn vũ trụ sẽ ở xung quanh" trong nhiều trường hợp. May mắn thay, hầu hết các trường hợp chỉ là 2-3 lớp, nhưng ngay cả sau đó, chúng tôi đã chạy trên nửa giờ. Hiện tại, chúng tôi lấy mẫu một tập hợp con rất nhỏ của các khả năng này, tăng độ chi tiết cho đến khi một khoảng thời gian đã đặt (hoặc chúng tôi đã hoàn thành nhiệm vụ, điều này có thể xảy ra đối với các cấu hình hai lớp nhỏ). Chúng tôi tăng ước tính này lên một chút dựa trên số liệu thống kê trước về mức độ thường xuyên chúng tôi bị chứng minh là sai, và sau đó thêm một chút phần đệm thêm cho biện pháp tốt.

Một ví dụ thú vị khác: trên một trò chơi trên PC, một kỹ sư trưởng đã thử nghiệm một lúc với các danh sách bỏ qua . Chi phí bộ nhớ kết thúc gây ra nhiều hiệu ứng bộ đệm hơn, thêm một số nhân không liên tục cho toàn bộ sự việc - vì vậy chúng thực sự không phải là một lựa chọn tốt cho nhỏ n. Nhưng đối với các danh sách được sắp xếp lớn hơn, nơi các tìm kiếm thường xuyên, chúng cung cấp một lợi ích.

. bộ dữ liệu.)


4

Nó có thể tiện dụng, nhưng nó cũng có thể không liên quan. Lấy ví dụ, trò chơi gần đây nhất của tôi, một cái gì đó của bản sao Smash TV. Trò chơi từ trên xuống, quái vật đổ vào từ hai bên, bạn bắn chúng.

Bây giờ có rất nhiều cách thông minh để xác định va chạm. Bạn có thể sử dụng KDtrees để phân vùng không gian để bạn không thử đạn chống lại quái vật mà chúng không thể bắn trúng. Và, chắc chắn, tôi có thể thông minh, và tôi có thể làm điều đó.

Nhưng tôi cảm thấy lười biếng nên tôi chỉ so sánh mọi viên đạn với mọi quái vật. Ngay cả trong những tình huống bận rộn nhất, mã va chạm đã sử dụng ít hơn 10% CPU trò chơi ở tốc độ 60fps. Big-O: Không quan trọng.

Tương tự, tôi có một trò chơi theo phong cách 4x, nơi bạn xây dựng các thành phố trên đảo và đôi khi các thành phố bị phá hủy. Tôi có thể đã thông minh và cố gắng trừ đi thu nhập của thành phố bị phá hủy từ các biến thu nhập. Nhưng tôi đã không làm thế. Tôi chỉ xóa sạch thu nhập và tính toán lại từ đầu mỗi khi có gì đó thay đổi. Hoàn toàn không liên quan về CPU.

Big-O cũng quan trọng trong các trò chơi cũng như trong mọi thứ khác: nghĩa là, hoàn toàn không quan trọng, cho đến khi nó trở nên quan trọng.

Đi viết một số mã. Nếu nó quá chậm, thì hãy cấu hình nó.


3

Phân tích Big-O rất quan trọng, nhưng đó không phải là điều đầu tiên cần nghĩ đến trong quá trình phát triển trò chơi. Vì làm cho các trò chơi liên quan đến nhiều mã phức tạp, tôi luôn đề xuất Đơn giản mã là tiêu chí đầu tiên cho thuật toán. Các thuật toán với sổ sách phức tạp chỉ lãng phí thời gian của bạn.

Tôi nghĩ điều thực sự quan trọng là trò chơi của bạn luôn chạy ở tốc độ 60 khung hình / giây trong quá trình phát triển. Khi bạn nhúng xuống dưới đó, điều đầu tiên bạn làm là chạy một hồ sơ. Một khi bạn tìm thấy nút cổ chai, bạn tấn công nó. Rất nhiều thời gian bạn cần để làm những thứ không mã hóa như nói với các nhà thiết kế cấp độ để đặt ít công cụ hơn trong một khu vực (và cung cấp cho họ công cụ cho việc đó).

Đôi khi bạn thực sự xác định một số mã cần được tăng tốc. Tôi thấy đây là kỹ thuật thú vị! Tôi ước tôi có nhiều cơ hội hơn để làm điều này. Và tất nhiên bạn muốn lặp lại thay đổi một điều tại một thời điểm và đo lường hiệu suất. Các vấn đề cơ bản tôi tìm thấy là:

  1. Đảm bảo bạn không gọi mới hoặc malloc mỗi khung (đây luôn là vấn đề số 1)
  2. Giảm công việc: ít tia hơn, ít kẻ hơn, v.v.
  3. Các vấn đề về loại thuật toán Big-O
  4. Tính liên kết của bộ đệm: Đặt nội dung trong mảng thay vì bộ nhớ phân tán
  5. Không sử dụng STL trong chế độ gỡ lỗi. (và bạn luôn muốn chế độ gỡ lỗi hoạt động)

2

Ký hiệu Big-O theo định nghĩa độ phức tạp tiệm cận - nghĩa là, nó cho thấy thời gian quy mô như thế nào khi N (hoặc bất kỳ biến nào bạn có) trở nên "rất" lớn. Để nhắc lại nhận xét của Tetrad (mà tôi đã nêu lên) "dữ liệu là vua". Nếu N là "rất lớn" trong tình huống cụ thể của bạn, thì đó là vấn đề, nếu N "rất nhỏ" thì không vấn đề gì. Kinh nghiệm và thực hành sẽ cho bạn cảm giác về cách định lượng "rất lớn" và "rất nhỏ".

Rõ ràng, luôn luôn hồ sơ đầu tiên, và tối ưu hóa cuối cùng (trừ khi bạn đang thực hiện một nghiên cứu tính khả thi).


1

Tầm quan trọng của Big-O trong phần mềm của bạn là O (N 2 ). Khi N phát triển, tầm quan trọng của việc có thuật toán phù hợp thậm chí còn tăng thêm. :)


Điều đó không phụ thuộc vào tần suất mà thuật toán đó được gọi là ..?
bobobobo

Đến một mức độ nào. Nhưng nếu phải mất 3 ngày để chạy, có lẽ không có vấn đề gì nếu bạn chỉ gọi nó một lần. :)
Kylotan

1

Big-O chỉ là một hướng dẫn - một cái gì đó cho bạn biết hiệu suất thô mà bạn có thể mong đợi từ một thuật toán - và cách bạn nên mong đợi hiệu suất sẽ mở rộng khi bạn tăng kích thước của tập dữ liệu . Bạn phải nhớ hai điều chính liên quan đến Big-O:

1) Nếu bạn có hai thuật toán chủ yếu làm cùng một thứ nhưng một thuật toán có O tốt hơn, có lẽ bạn nên dùng thuật toán đó (rõ ràng)

2) Big O liên quan đến phân tích tiệm cận . Big-O chỉ thực sự phát huy tác dụng khi n lớn . Ví dụ, thuật toán O (n) có thể có hiệu suất rất giống với thuật toán O (n ^ 2) .. đối với n nhỏ . Nếu bạn đang nói về một thuật toán đòi hỏi n ^ 2 hoạt động mỗi đỉnh, nhưng n = 2 hoặc n = 3, sau đó không phải là nhiều khác biệt giữa một O (n ^ 2) Thuật toán (dùng 4 và 9 ops resp) và một O (n) một (2 và 3 ops resp.). Tuy nhiên, nếu n = 9, thì bạn đột nhiên nói về 81 thao tác cho thuật toán O (n ^ 2) và chỉ 9 cho thuật toán O (n) - một sự khác biệt lớn hơn - và nếu n = 100, thì bạn là nói về 100 ops so với 10000 - một sự khác biệt lớn hơn nhiều.

Vì vậy, bạn phải luôn luôn xem xét Big-O trong ánh sáng đó: nó có nghĩa là để so sánh các thuật toán làm điều tương tự dựa trên hiệu suất trường hợp xấu nhất khi n trở nên lớn . Sự khác biệt giữa các thuật toán có thể là tất cả nhưng không đáng kể khi n rất nhỏ.


0

Tôi không có tài liệu tham khảo nhưng Big O ít nhất là tiện dụng để nhận biết khi phân tích một vấn đề và thảo luận. Mặt khác, tất nhiên, nếu phiên bản O (log n) có nhiều cách liên quan đến O hơn phiên bản O (n) thì đó là một so sánh tranh luận. Và như với mọi thứ, luôn có một sự đánh đổi. Sự phức tạp không gian có thể là một vấn đề, mặc dù điều đó cũng có thể được thể hiện bằng O nói chung. Phân tích trường hợp bình thường ... ít hơn, vì bạn không muốn các ngoại lệ tăng đột biến. Theo tôi, sự đơn giản so với sự phức tạp là tương đối vô dụng trong việc phát triển trò chơi vì tốc độ hầu như luôn là một vấn đề, vì vậy trừ khi sự đơn giản dẫn đến tăng tốc (nhưng sau đó, điều đó có nghĩa là trường hợp phức tạp của bạn đã sai vì những lý do sai lầm) ra khỏi cửa sổ ủng hộ tốc độ. Nhưng Big O chắc chắn rất hữu ích,


0

Khi bạn tạo thử nghiệm một chức năng trò chơi hoặc một khía cạnh của một trò chơi, bạn không nên lo lắng về việc tối ưu hóa nó ở tất cả .

Trong quá trình tạo mẫu và tìm hiểu về các đặc điểm riêng của chức năng đó, các tối ưu hóa cần thiết sẽ trở nên rõ ràng và sẽ là yếu tố thiết kế cuối cùng như bản chất thứ 2 ... hầu hết thời gian.

Đừng đổ mồ hôi.


"Khi bạn tạo nguyên mẫu một chức năng trò chơi hoặc một khía cạnh của trò chơi, bạn không nên lo lắng về việc tối ưu hóa nó." Điều này đôi khi đúng nhưng không phải lúc nào cũng vậy. Một số trò chơi, như Dead Rising, dựa vào thực thi nhanh để biến cơ chế trò chơi cốt lõi - hàng trăm zombie trong thời gian thực - khả thi.

Bao nhiêu phần trăm phát triển trò chơi là nguyên mẫu? Cuối cùng bạn muốn gửi một cái gì đó , phải không?
dash-tom-bang

0

Nó không nên là tất cả và cuối cùng. Nhưng nó giúp loại bỏ các vấn đề rõ ràng có thể gây ra hiệu suất; Tại sao sử dụng một cái gì đó trong thời gian O (n ^ 2), khi bạn có thể làm điều tương tự trong thời gian O (log n)?

Tôi nghĩ rằng nó áp dụng cho các trò chơi nhiều hơn hầu hết các ngành công nghiệp khác, vì thị trường là nơi sẽ chú ý nhiều nhất đến các vấn đề tốc độ. Ai đó sử dụng trình xử lý văn bản sẽ không quan tâm nếu có độ trễ nửa giây khi thực hiện hành động X, nhưng các game thủ có thể sẽ chơi 'omg omg trò chơi Y rất chậm nên mất nhiều thời gian để thực hiện hành động Z'.


0

Trong phát triển trò chơi (và hầu hết các thứ khác), chúng tôi đang than vãn về một hoạt động bổ sung được thực hiện trên mỗi vòng lặp:

for (int i = 0; i < array.length; i ++) { /* ... */ }

so với

for (int i = 0, l = array.length; i < l; i ++) { /* ... */ }

Hầu hết các trò chơi hiện đại đều có vật lý, và bạn sẽ tìm thấy vấn đề mô phỏng n-body . Trong một thuật toán ngây thơ, đó là O (n ^ 2), nhưng có một tối ưu hóa làm cho nó O (n log n) (nhưng hy sinh một số độ chính xác).

Bạn có thể nói, bạn không lập trình các tương tác trọng lực và hạt, nhưng còn hành vi đội của một đội quân (của thây ma) nơi chúng di chuyển phụ thuộc vào các vị trí khác (nói một cách cụ thể hơn: tràn ngập)?

Trong thuật toán phát hiện va chạm thông thường, độ phức tạp thời gian là O (n ^ 2), giống như cơ thể n. Tuy nhiên, có một cách tốt hơn: Tách thế giới thành nhiều phần nhỏ để chỉ các vật thể bên trong cùng một phần được phát hiện va chạm. Xem http://www.videotutorialsrock.com/opengl_tutorial/collision_detection/text.php .

Nếu trò chơi của bạn có thể viết được tập lệnh, KHÔNG làm cho tập lệnh viết các thuật toán bẻ khóa số O (n ^ 2) (và lên) trong tập lệnh, chẳng hạn như tìm kiếm túi của người dùng. Thay vào đó hãy tạo một hàm dựng sẵn trong mã.


1
Cả hai ví dụ mã của bạn là O (n). Các cuộc thảo luận về Big-O không liên quan gì đến "một thao tác bổ sung trên mỗi vòng lặp", mà là "một tìm kiếm thêm thông qua mọi thứ trên mỗi lần lặp của vòng lặp trên tất cả mọi thứ."
dash-tom-bang

-2

Trong thế giới thực chỉ có hiệu suất thô tính. Bây giờ, Big-O của một thuật toán có thể đóng vai trò là dấu hiệu đầu tiên cho việc sử dụng cái gì, nhưng tùy thuộc vào phần cứng, việc triển khai có thể không hiệu quả khủng khiếp. Ví dụ: thực hiện tìm kiếm tuyến tính thường có thể nhanh hơn tìm kiếm nhị phân vì bạn có quyền truy cập bộ nhớ tuyến tính và không có chi nhánh.

Ngoài ra, do hướng hiện tại trong các nền tảng và kiến ​​trúc đa luồng, Big-O đang mất rất nhiều ý nghĩa vì nó chỉ tính đến khả năng mở rộng theo chiều dọc của bộ nhớ hoặc dữ liệu chạm vào mỗi thao tác thay vì cũng tính đến thuật toán quy mô với số lượng lớn hơn của chủ đề.


3
Điều này là không chính xác, ký hiệu Big O được sử dụng để hiển thị giới hạn trên của các thuật toán song song giống như các thuật toán tuyến tính. Big O có thể được sử dụng cho các kiến ​​trúc đọc / ghi đồng thời, v.v. Bạn thậm chí có thể làm những việc điên rồ như sắp xếp trong O (1) với n ^ 2 bộ xử lý hah
David Young

David, bạn có bất kỳ ví dụ thực tế? Ý tôi là, tôi cũng có thể Big-O số táo mà một nhóm người có thể mang theo, nhưng điều đó không có nghĩa là nó được sử dụng hoặc hữu ích. Từ kinh nghiệm của tôi, hầu hết thời gian gamedev chọn thuật toán (song song) của họ dựa trên hiệu suất thô, không dựa trên các chức năng tăng trưởng của họ.
Jasper Bekkers

3
"Sắp xếp trong O (1) với n ^ 2 bộ xử lý" Tôi thường cảm thấy rằng việc sử dụng O này là sai lệch vì việc sử dụng tài nguyên vẫn là O (n ^ 2) cho dù bạn có xử lý vấn đề theo cách nào. Số lượng luồng lớn hơn không chỉ có nghĩa là số chu kỳ cpu lớn hơn mỗi giây.
Richard Fabian

Sắp xếp theo O (1) với bộ xử lý n ^ 2 không phải là ví dụ tốt nhất, loại ký hiệu Big-O này có lẽ thường thấy nhất trong giới hàn lâm. Một cái gì đó giống như cs.bu.edu/~best/crs/cs551/homeworks/hw1/pram.html Các thuật toán song song thực tế hơn có thể sử dụng bộ xử lý log (n). Loại công cụ này phù hợp hơn với việc quá tải vào xử lý GPU hoặc siêu điện toán nơi có hàng trăm lõi có sẵn.
David Young

Tôi có nghĩa là giảm tải, không quá tải. Không thể chỉnh sửa nhận xét ban đầu của tôi nữa.
David Young
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.