Có thực tế khi từ bỏ STL trong phát triển C ++ không? [đóng cửa]


19

Tôi biết trong một số lĩnh vực (ví dụ như ngành công nghiệp trò chơi), STL không được khuyến khích. Vì vậy, câu hỏi của tôi là: nó thực sự là một thực hành tốt không sử dụng STL trong một số trường hợp? Nếu vậy, lý do lớn nhất của việc không sử dụng STL của C ++ hiện đại là gì?



Một số đồng nghiệp của tôi lập luận rằng, trình vòng lặp làm cho việc gỡ lỗi khó khăn hơn, bởi vì đôi khi không dễ để bước vào và điều này cũng được áp dụng cho lambda. Phản ứng của bạn là gì?
Thuyền trưởngJH

Đối với việc bỏ qua nội dung trong quá trình gỡ lỗi, hãy xem, ví dụ: stackoverflow.com/questions/2062881/iêu
Martin Ba

Đây có vẻ là một câu hỏi hay. Có lẽ ai đó có thể thêm "Tại sao một dự án chọn không sử dụng STL?"
Matthew James Briggs

Câu trả lời:


25
  • Tôi chỉ có thể nghĩ về một lý do hợp lệ và nó thực sự hiếm: Thời gian thực khó khăn. Nhiều thứ trong thư viện chuẩn phân bổ bộ nhớ trong và điều đó không đủ tính xác định cho các ứng dụng thời gian thực cứng, vì vậy chúng phải được tránh. Các ứng dụng này thường khá đơn giản, mặc dù chúng mất thời gian không tương xứng để phát triển do việc xem xét và kiểm tra rất nghiêm ngặt.

  • Tôi có thể nghĩ về một lý do không hợp lệ, nhưng rất phổ biến: Các nhà phát triển không hiểu độ phức tạp tính toán, lạm dụng STL và sau đó đổ lỗi cho thư viện.

    STL thường nhanh hơn trong thời gian chạy so với các giải pháp kiểu C với các con trỏ gọi lại hoặc các giải pháp dựa trên đa hình với các phương thức ảo ( xem thêm bài phát biểu của Bjarne Stroustrup này ). Tuy nhiên, khi nhà phát triển không hiểu các thông số kỹ thuật phức tạp được đưa ra và sử dụng sai thư viện bằng cách tạo ra thứ gì đó như vectơ của một số đối tượng phức tạp (trong C ++ 11, nó không còn là vấn đề nữa!), Gây ra vấn đề về hiệu năng và hơn là tự bảo vệ với "bạn thấy đấy, các vectơ khá chậm", nó có thể gây ra nhận thức rằng thư viện chuẩn bị chậm. Và một khi các nhà quản lý có được nhận thức như vậy, nó có thể sống rất lâu trong tổ chức.

  • Rõ ràng bạn không thể sử dụng bất cứ thứ gì mà nền tảng bạn đang nhắm mục tiêu không hỗ trợ. Tuy nhiên, chúng tôi hiện đang nhắm mục tiêu bốn nền tảng di động phổ biến nhất (Android, iOS, Bada và WinCE cũ) và sử dụng thư viện tiêu chuẩn và một số phần của Boost trên tất cả chúng.

    Phần lớn thư viện tiêu chuẩn từng được Microsoft không hỗ trợ sớm trong WinCE (IIRC iostreams chỉ xuất hiện với Visual Studio 2005), nhưng thay vào đó, có thể sử dụng STLport từ lâu. Và bạn thường có thể có được điều đó để biên dịch cho bất cứ điều gì. Vì vậy, tôi sẽ gọi lý do này là không hợp lệ là tốt.

    Bên cạnh đó, trong một thời gian khá dài, nó không phải là "STL", mà là Thư viện tiêu chuẩn ANSI C ++. Nó được định nghĩa bởi cùng một tài liệu tiêu chuẩn xác định chính ngôn ngữ đó. Bất cứ điều gì không hỗ trợ, nó không thực sự xứng đáng được gọi là C ++.


6
Đối số đầu tiên (thời gian thực) không dành riêng cho các phần STL của Thư viện chuẩn. sprintfthường phân bổ bộ nhớ quá. Trên nền tảng thời gian thực, các chức năng thư viện tiêu chuẩn cũng có giới hạn xác định. Điều này làm cho việc triển khai C ++ trong thời gian thực trở nên khó khăn: bạn phải phát triển cẩn thận toàn bộ thư viện chuẩn C ++, công việc này không chỉ là thư viện chuẩn C nhỏ.
MSalters

@MSalters: Chắc chắn, nhiều thứ không thể được sử dụng theo yêu cầu thời gian thực. Ngay cả một số tính năng ngôn ngữ như ngoại lệ không thể. Still C ++ là ngôn ngữ tuyệt vời cho các hệ thống này, bởi vì nó có thể kết hợp hiệu suất và kiểm soát chính xác với các biện pháp bảo vệ mạnh mẽ (RAII là tính năng quan trọng nhất cho điều đó).
Jan Hudec

@JanHudec: Thật vậy, đó là lý do tại sao các phần STL chỉ được yêu cầu cho việc triển khai "lưu trữ" của C ++.
MSalters

7

Tôi đang sử dụng STL và tăng trong nhiều năm. Nếu tôi muốn từ bỏ nó và sử dụng các công cụ tùy chỉnh của mình, động lực sẽ là:

  1. Biên dịch giảm thời gian (75%). Chỉ cần bao gồm các iostream có thể thêm 1 triệu dòng mã vào mô-đun của bạn. Có các tiêu đề được biên dịch trước giúp ích rất nhiều, nhưng nó vẫn làm chậm quá trình biên dịch rất nhiều trong các dự án lớn. Về lâu dài, nó lãng phí rất nhiều thời gian của bất cứ ai làm việc trên nó.
  2. Hiệu suất. (25%) STL được viết để hoạt động nói chung, nhưng bạn có thể tối ưu hóa các cấu trúc của mình để hoạt động chính xác như bạn muốn. Ví dụ: bạn có thể có cấu trúc dữ liệu với hàng triệu chuỗi ngắn. Có thể nhanh hơn nhiều khi sử dụng lớp chuỗi tùy chỉnh dựa trên hiệu trưởng của boost :: small_vector (vectơ dữ liệu cục bộ tĩnh nhỏ, chỉ phân bổ động cho các chuỗi lớn hơn), những thay đổi này có thể làm cho các phần mã quan trọng hoạt động nhanh hơn nhiều lần.

1
SSO đã phổ biến.
Ded repeatator

cho hậu thế: SSO -> tối ưu hóa chuỗi nhỏ, tức là hầu hết (tất cả?) std :: triển khai chuỗi giữ chuỗi nhỏ trên ngăn xếp và chuyển sang heap nếu cần
màu xanh

Thời gian biên dịch là một lần lớn
dùng1754322

4

Có một lý do hợp lệ lớn để không sử dụng thư viện mẫu tiêu chuẩn C ++: Một trong những nền tảng mục tiêu của bạn không có triển khai tuân thủ hoàn toàn (hoặc không thực hiện gì cả) và bạn biết rằng nó sẽ không nhận được một trong những năm tiếp theo


3
Aka "không sử dụng nó khi bạn không có nó", điều đó thực sự có ý nghĩa. :)
Xèo

4
Cho rằng thư viện chuẩn C ++ 03 được thiết kế để chỉ được triển khai theo thư viện ANSI C89, có nền tảng nào mà bạn không thể có ít nhất STLPort không?
Jan Hudec

@JanHudec Tôi tin rằng có những nền tảng không có STL vì chúng không có đủ bộ nhớ để xử lý toàn bộ. Thông thường họ cũng thiếu một số chức năng C ++ khác (ví dụ: ngoại lệ).
Sulthan

2
@Sulthan: Đối với những người vi điều khiển tôi hơi hiểu, nhưng những người đó thuộc loại "thời gian thực cứng" thường. Đối với bất cứ điều gì khác, đó chủ yếu là các định kiến, bởi vì STL thường hiệu quả cả về bộ nhớ và hiệu năng như mã thủ công. Rất nhiều nội tuyến có thể gây ra nhị phân lớn hơn, nhưng điều đó thậm chí có thể tránh được bằng cách thực hiện cẩn thận với một số chi phí hiệu suất (rằng một giải pháp thủ công cũng sẽ có). Thiếu ngoại lệ cũng là định kiến, hoặc lười biếng, bởi vì cần nỗ lực để xác định và thực hiện ngoại lệ ABI.
Jan Hudec

4

Tôi không biết về độ phức tạp (hiệu quả thực hiện) nhưng tôi đang sử dụng các bộ chứa và chuỗi Qt rộng rãi thay vì các tiêu chuẩn và chúng hoạt động tốt. Tôi cũng thấy việc thực hiện Qt của các bộ và danh sách dễ sử dụng hơn.

Vì vậy, việc từ bỏ STL là điều thiết thực nếu bạn có thể sử dụng một thư viện khác phù hợp với nhu cầu của mình.


2
tương đương Qt đã được tạo ra cách trở lại khi không có triển khai STL nào là a) có sẵn hoặc b) bất kỳ hàng hóa nào. Đó là lý do duy nhất chúng vẫn được sử dụng, không có gì chống lại STL ngày nay.
gbjbaanb

1
@Giorgio: vấn đề là ở các ứng dụng phức tạp, nơi bạn đang kết hợp nhiều thư viện. Các container STL, là tiêu chuẩn, tạo thành một ngôn ngữ chung . Chính xác hơn, đó là quy ước của họ. Ví dụ nổi tiếng nhất là Boost. Nó có thể hoạt động trên các container STL. nó cũng có thể làm việc trên container Qt, nhưng chỉ vì Qt có sau công ước STL - ví dụQList<T>::iterator
MSalters

3
Tôi đã không đánh giá thấp nó, nhưng tôi thấy một lý do: Nó không trả lời câu hỏi. Bạn nói rằng có những thứ để sử dụng thay vì STL, tốt thôi, nhưng đó không phải là lý do để tránh STL. Bên cạnh bất kỳ lý do nào để tránh STL có thể áp dụng cho Qt, MFC và các thư viện khác như vậy hoặc thậm chí nhiều hơn.
Jan Hudec

3
@NoOne: Chúng tôi hiểu rằng bạn đã quen với lạc đà, không phải snakecase, nhưng điều đó không làm cho cái sau trở nên tồi tệ hơn. Và trong ba tên hàm mà bạn chỉ trích, đầu tiên là mô tả hoàn hảo cho bất kỳ ai có liên quan đến chuỗi c và hai tên còn lại được kế thừa từ C, sẽ không thảo luận về chúng.
Ded

1
@NoOne: Như tôi đã nói, tôi hoàn toàn hiểu rằng bạn cảm thấy thoải mái hơn với CamelCase.
Ded

3

Patrick đã đề cập đến lý do không sử dụng toàn bộ STL, cụ thể là (các) nền tảng của bạn không có.

Tất cả trong tất cả tôi nghĩ rằng câu hỏi đang thiếu điểm. Đó không phải là một quyết định tất cả hoặc không có gì, mà là một trong những lựa chọn và lựa chọn. Bạn cũng có thể quyết định sử dụng các thùng chứa và thuật toán, nhưng quyết định sử dụng một cái gì đó bên ngoài Std Lib cho chuỗi và i / o.


3

Nó không thực tế, trừ khi có một lý do nặng nề để làm như vậy. Một số lý do như vậy mà tôi có thể nghĩ đến chỉ bao gồm triển khai STL một phần hoặc thiếu (hoặc bất kỳ phần nào khác của thư viện chuẩn) hoặc giới hạn tài nguyên (bộ nhớ, tốc độ CPU, lưu trữ, ...) mà bạn phải khắc phục lăn các công cụ của riêng bạn mà tuân thủ những gì bạn cần phải hoàn thành.

Trong ngành công nghiệp trò chơi, hầu hết các studio (thậm chí nhỏ hơn ở một mức độ nào đó) đều có thư viện nội bộ và triển khai nhiều phần thư viện tiêu chuẩn được thiết kế riêng cho nền tảng đích và trong một số trường hợp nhắm mục tiêu engnie hoặc thậm chí là chính trò chơi. Nói một cách đơn giản khi phát triển một trò chơi dành cho bảng điều khiển, phần cứng rất hạn chế bởi các tiêu chuẩn ngày nay. Có hàng ngàn và hàng ngàn dây chuyền lắp ráp thủ công vì một lý do. Điều rất quan trọng là giảm thiểu tất cả các loại dấu chân tài nguyên trong mã của bạn để trò chơi chạy nhanh hơn, cho phép nhiều nội dung hơn trong thế giới trò chơi (ví dụ như một thế giới lớn hơn) hy vọng sẽ mang lại một sản phẩm tốt hơn.

"Mỗi trò chơi thành công bắt đầu bằng cách triển khai thực hiện danh sách liên kết của riêng bạn."


1
Tôi sẽ tưởng tượng mọi trò chơi thành công bắt đầu bằng cách viết mã bằng thư viện tiêu chuẩn và sau đó chỉ tối ưu hóa mã khi trò chơi đã được định hình rộng rãi. Tối ưu hóa trước khi bạn có hồ sơ dữ liệu nêu rõ những gì cần tối ưu hóa là vô nghĩa.
Cromulent

Thật. Cụm từ cuối cùng chỉ là một cách chơi theo cách viết trò chơi "cổ xưa" vào đầu những năm 90 hoặc lâu hơn, khi C ++ không được triển khai rộng rãi và lắp ráp + C là cách để đi. Có lẽ tôi nên nói rõ hơn. Mặc dù vậy, nó cũng áp dụng tốt cho ngành công nghiệp trò chơi, hầu hết các cấu trúc dữ liệu và cấu trúc dữ liệu đều được viết bằng tay vì mỗi byte và chu kỳ đều có giá trị (có, thậm chí với chi phí bảo trì / tính di động / bất cứ điều gì).
zxcdw

2
Cần phải nói rằng, đó là nhiều hơn một kinh nghiệm cũ sống. Trình tối ưu hóa hiện đại thường sẽ tạo ra sự lắp ráp tốt hơn từ mã có thể bảo trì đơn giản hơn so với lập trình viên sẽ làm bằng tay và các mẫu chung như trong STL hoặc Boost thường nội tuyến thành mã hiệu quả như mọi thứ bằng tay đặc biệt. Nhưng có rất nhiều mã bắt đầu trong thời gian đó không phải là trường hợp đó và rất nhiều người đã học giao dịch những ngày đó và tiếp tục làm việc theo cách đó mặc dù nó không còn ý nghĩa nữa.
Jan Hudec

2
@JanHudec Điều là các triển khai (và hành vi cũng vậy, nguyên vẹn) cần phải được điều chỉnh rất phù hợp cho nhiệm vụ. Bạn chỉ đơn giản là không thể dự phòng vài chục byte ở đây và ở đó (phá hỏng địa phương của tham chiếu), thả vào một vài nhánh để xác thực đầu vào (lỗi sai nhánh và bộ nhớ cache hướng dẫn) và giả sử rằng trình biên dịch biết cách vector hóa cấu trúc dữ liệu của bạn tối ưu hóa để tận dụng lợi thế của SIMD (nó sẽ không hoặc ít nhất bạn phải xác minh rằng những gì nó cố gắng là chính xác). Tất nhiên, việc viết phần mềm thời gian thực trên PC không nghiêm ngặt, bạn luôn có thể sử dụng CPU nhanh hơn. Không trong bảng điều khiển.
zxcdw
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.