Các tham chiếu giữa các tài sản nên được xử lý theo tên hoặc ID hoặc cái gì khác?


7

Làm thế nào các mục nội dung hoặc tài sản nên được tham chiếu ở dạng tuần tự của chúng?

Ví dụ, một vật liệu có thể cần tham khảo một số kết cấu. Cách đơn giản nhất là sử dụng một đường dẫn, liên quan đến thư mục cơ sở của tài sản.

Ngoài ra, tất cả các mục nội dung có thể được tham chiếu bằng ID. Tôi đã triển khai theo cách này (sử dụng GUID), cho phép các mục nội dung được đổi tên hoặc di chuyển mà không phá vỡ các tham chiếu. Tuy nhiên, điều này khiến việc thay thế một mục nội dung trở nên khó khăn hơn (xóa bản gốc, sau đó đổi tên một cái khác thành cùng tên ... yêu cầu sao chép / dán GUID xung quanh). Nó cũng làm cho việc gỡ lỗi thiếu nội dung phức tạp hơn.

Có một lựa chọn chiến thắng rõ ràng ở đây?


Tôi đã sử dụng UUID và chúng dường như dễ tạo ra và có xác suất va chạm thấp đến mức nực cười
Alex Stone

Câu trả lời:


8

Khóa chuỗi / Hashmap

  • Rất nhanh, vì thời gian đọc được khấu hao O (1), có nghĩa là truy cập đọc thường rất nhanh, nhưng trong trường hợp xấu nhất (hiếm, nhưng không phải là chưa từng nghe thấy), nó có thể khá chậm. Trường hợp xấu nhất kết quả từ va chạm băm.

  • Việc triển khai đôi khi phải được xây dựng hoặc tìm thấy (ví dụ, trong C). Viết / tìm một triển khai bản đồ có khóa chuỗi biểu diễn có thể không tầm thường.

  • So sánh chuỗi có thể tốn kém, mặc dù điều này có phù hợp hay không phụ thuộc vào việc bạn thực hiện cả hai hàm băm đọc opmap và thực hiện bình đẳng chuỗi.

  • Có thể khiến bạn vô tình tạo các bản sao hoặc ghi đè các giá trị hiện có (phụ thuộc vào việc triển khai).

Khóa / mảng số

  • Rất nhanh, vì cấu trúc bạn thêm vào bản đồ trực tiếp vào bộ nhớ (theo mảng trong hầu hết các ngôn ngữ)

  • Rất nhanh, vì tính bằng số được kiểm tra nhanh chóng (ít nhất là đối với băng thông bit đủ nhỏ)

  • Rất nhanh, bởi vì các mảng dài, được phân bổ liên tục có thể có hiệu suất bộ đệm tuyệt vời (báo trước: điều này phụ thuộc rất nhiều vào lựa chọn ngôn ngữ và cách triển khai của bạn).

  • Yêu cầu "GUID" của bạn không quá lớn để hoạt động như một chỉ mục mảng. Tuy nhiên, các tùy chọn nhanh có thể được tìm thấy để giải quyết vấn đề này, chẳng hạn như chia nhỏ ID của bạn (thông qua bit op) để sử dụng như hai chỉ số đủ ngắn cho mỗi phần tử trong một mảng 2D.

  • Thật bất tiện, vì những lý do bạn đã đề cập. Nếu ID là các giá trị thời gian biên dịch mà bạn cần để có thể phát triển, thì đó không phải là vấn đề, vì chúng có thể được gán cho các hằng số TẤT CẢ CAPS được đặt tên một cách thích hợp và được sử dụng theo cách đó.

  • Có thể tham chiếu cấu trúc có chứa một tên người có thể đọc được. Điều này cung cấp một số tiện lợi, ngay cả khi tên này không thể được truy cập.

Phần kết luận

Trừ khi bạn sẽ xử lý nhiều yếu tố (giả sử, hàng chục nghìn) cho mỗi 16-20ms đánh dấu bằng cách sử dụng một trong các tùy chọn này, tôi sẽ không lo lắng về ID số và đặc biệt nếu bạn đang sử dụng ngôn ngữ có sẵn các hashtag hiệu quả , chỉ cần chọn cho một hashmap.

Mặt khác, cách tiếp cận ID / mảng số là tốt để bảo toàn chu kỳ CPU, nhưng hãy thực hiện điều này trong trường hợp tài nguyên có giá cao.


6

Tôi đặc biệt ủng hộ việc sử dụng ID và đặc biệt là GUID. GUID có một số lợi thế tuyệt vời:

  • Chúng có thể được tạo ra tại địa phương và vẫn giữ được tính độc đáo của chúng. ID số đơn giản yêu cầu cơ quan trung ương đảm bảo tính duy nhất, điều này khiến chúng ngay lập tức trở nên cồng kềnh hơn khi bạn sử dụng nhiều hơn một người làm việc trong một dự án.

  • Thay đổi tên của một tài sản không đòi hỏi hoạt động tốn kém trong việc định vị tất cả các tham chiếu đến tên cũ đó và cập nhật chúng. Không chỉ dễ bị lỗi này, nó còn có vấn đề nghiêm trọng trong một thế giới nơi nhiều người đang cộng tác trên một tập dữ liệu (nếu ai đó đang làm việc trên một tệp tham chiếu đến tệp bạn đang thay đổi, thì bạn buộc phải chờ hoặc họ buộc phải giải quyết hợp nhất).

  • Di chuyển tài sản xung quanh trong hệ thống tệp hoặc phân cấp logic của kho nội dung cũng không yêu cầu cập nhật bất kỳ tài liệu tham khảo nào .

GUID có nhược điểm, nhưng tất cả đều có thể giải quyết được với một chút nỗ lực.

  • Chúng rất khó nhớ và gõ, điều đó có nghĩa là có thể khó cộng tác với người dùng khác ("Nhìn vào đối tượng {CD0B6FBB-1156-4BCF-A5EB-82967376090E}" hơi cồng kềnh). Tuy nhiên, bạn có thể xây dựng vào chuỗi công cụ chỉnh sửa tài sản của mình một cách để tìm kiếm các đối tượng theo tên hoặc thậm chí tốt hơn, xây dựng sơ đồ URL cho các công cụ của bạn cho phép bạn tạo các liên kết có thể nhấp để tải lên các công cụ xem nội dung mong muốn.

  • Họ to lớn. Điều này thường không phải là mối quan tâm nhiều trong quá trình phát triển, nhưng là để vận chuyển mã. Tuy nhiên, thật dễ dàng để hỗ trợ bước thời gian biên dịch dữ liệu tạo ra ánh xạ lại từ GUID sang ID số nguyên khi nướng nội dung cuối cùng cho trò chơi.

Trong Guild Wars 2, chúng tôi đã sử dụng các tham chiếu có tên cho nội dung trong vài năm đầu phát triển. Đó là quyết định sai lầm và cản trở hiệu suất của các công cụ của chúng tôi trong một thời gian khá lâu trước khi chúng tôi có thể chuyển sang GUID. Mọi dự án tôi từng làm với các tài liệu tham khảo có tên được sử dụng đều gặp rắc rối với chúng, vì vậy tôi hoàn toàn khuyên bạn nên chống lại chúng. Nỗ lực cần có để xây dựng công cụ hỗ trợ xung quanh GUID là ít hơn, về lâu dài, nó sẽ phải đối phó với các tham chiếu có tên.

Nếu bạn có một dự án nhỏ, chỉ cần một mình hoặc có thể một số ít người khác bạn có thể thoát khỏi bằng cách sử dụng ID (ví dụ, cung cấp cho mỗi người một "khối" ID chuyên dụng, có thể dễ dàng tránh được sự cố xung đột trong một thời gian). Nhưng nếu bạn có một dự án nhỏ thì chi phí của GUID cũng không có vấn đề , vì vậy tôi chỉ nói rằng bạn nên sử dụng những dự án đó để có khả năng mở rộng tốt nhất trong tương lai.


1

Sẽ dễ dàng hơn để suy nghĩ về nó khi bạn phân biệt giữa định danh bên ngoài và định danh bên trong. Một tài sản có một mã định danh bên ngoài duy nhất được tham chiếu trong các tệp cấu hình, tệp tạo, tài liệu, v.v. Một khi tài sản đã được tải vào ứng dụng của bạn, các tài sản có thể nhận được một mã định danh nội bộ hiệu quả để tham chiếu nội bộ.

Đối với định danh bên ngoài, tôi sẽ sử dụng sơ đồ đặt tên nhất quán, theo quy ước về cấu hình mô hình. Vì vậy, bạn có thể muốn sử dụng sơ đồ dựa trên đường dẫn, chẳng hạn như 'tài nguyên / kết cấu / tường / Concrete.png'. Mã định danh này cho bạn biết rất nhiều: đó là một tài nguyên, rằng nó là một kết cấu, nó thuộc về 'bức tường' của nhóm kết cấu và thậm chí là nơi nó có thể được tìm thấy trên đĩa. Thêm vào đó, nó dễ đọc với con người, hơn cả GUID.

Đối với mã định danh nội bộ, bạn có thể chọn sử dụng vị trí bộ nhớ (con trỏ), tăng số nguyên hoặc GUID. Tất nhiên, bạn cũng có thể chọn sử dụng mã định danh bên ngoài làm định danh lý tưởng của mình, với chi phí sử dụng bộ nhớ cao hơn và hiệu suất chậm hơn.

Để có được một định danh nội bộ từ định danh bên ngoài của bạn, rất có thể bạn sẽ cần một bản đồ / kho lưu trữ trung tâm trong ứng dụng của bạn. Thông thường, người quản lý tải tài nguyên của bạn có thể được sử dụng cho việc này.

Cuối cùng, về điểm thiếu tham chiếu: vì tài nguyên thường được tải nhanh khi chạy, bạn nên có một số loại kiểm tra bộ kiểm tra hoặc tính toàn vẹn cho ứng dụng của bạn, vì vậy tôi không nghĩ nó sẽ quan trọng đến loại định danh nào Đề án bạn sẽ sử dụng.


0

Không có cách tiếp cận tốt nhất, bởi vì nó luôn phụ thuộc vào trường hợp sử dụng thực tế và kiến ​​trúc tổng thể của bạn.

Sử dụng ID hoặc GUID không nhất thiết phải dễ sử dụng hoặc thay thế. Chỉ cần nhớ rằng bạn sẽ phải sao chép và sử dụng chúng. Đặc biệt GUID thường khá dài và khó nhớ mà không cần sao chép. Điều tương tự có thể đúng với số nguyên của một số loại.

Như vậy, tên "biết nói" có lẽ là cách tiếp cận tốt nhất, ngay cả khi điều này liên quan đến việc viết hoặc thay thế nhiều hơn.

Những gì bạn có thể làm, là sử dụng một số định danh độ dài cố định. Ví dụ: bạn có thể sử dụng 4 ký tự chữ và số để xác định mọi thứ. Điều này cũng có một lợi thế bổ sung, đó là bạn sẽ có thể dễ dàng truyền ID (chuỗi) thành một số nguyên (chỉ cần lưu ý đến sự khác biệt về thứ tự byte) và so sánh nó một cách nhanh chóng.

Điều này cũng có thể được mở rộng thành tên tệp, vì vậy bạn sẽ không phải tham khảo đường dẫn đầy đủ. Ví dụ: nếu tôi sử dụng "NMY1" cho kẻ thù đầu tiên của mình, dữ liệu đó sẽ được lưu trữ trong tệp "NMY1.dat", với kết cấu nằm trong "NMY1.png", mã tập lệnh trong "NMY1.lua", v.v.

Một điều nữa sẽ là khả năng sửa đổi: Nếu bạn muốn người dùng có thể dễ dàng sửa đổi trò chơi của mình, hãy cố gắng tránh tối đa hóa nó. Tức là thích nói tên hơn viết tắt, không sử dụng ID thô hoặc GUID và sử dụng một cái gì đó dễ đọc / hiểu / sao chép hơn, ngay cả khi điều đó có nghĩa là bạn cũng có thể phải cập nhật nhiều tài liệu tham khảo.

Nếu dữ liệu của bạn quá phức tạp để dễ dàng cập nhật / kiểm tra, hãy viết các công cụ để làm điều đó cho bạn (và để xác minh tính toàn vẹn) hoặc suy nghĩ lại về cách tiếp cận của bạn.

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.