Điều gì làm cho một sản phẩm phần mềm lớn và phức tạp chậm? [đóng cửa]


16

Vì một lý do phần lớn không liên quan, tôi đã cài đặt Delphi 7 một lần nữa trong một thời gian dài như vậy. Tôi phải nói rằng, tôi đã hoàn toàn bị thổi bay - theo cách mà tôi đã không được một lúc. Đây không phải là cách tôi nhớ mọi thứ. Quá trình cài đặt mất khoảng 30 giây. Ra mắt mất 2 giây và ngay lập tức có thể sử dụng được. Tôi có thể nhấn "Chạy" lần thứ hai sau khi nó bắt đầu và chưa đầy một giây sau, chương trình trống đã hiển thị và đang chạy. Chiến công cho máy tính trở nên nhanh hơn rất nhiều!

Nhưng lý do tôi bị thổi bay như thế này là vì thường tôi sử dụng Visual Studio 2010, điều đó hoàn toàn không cảm thấy buồn cười như thế này. Cấp, Delphi 7 là một hệ thống nhỏ hơn nhiều so với Visual Studio 2010, nhưng nó có vẻ như có tất cả những thứ thực sự cần thiết ở đó: bảng điều khiển, trình thiết kế biểu mẫu, trình chỉnh sửa mã với hoàn tất mã. Tôi nhận ra rằng ngôn ngữ có thể đơn giản hơn và việc hoàn thành mã có thể kém hơn rất nhiều và IDE có thể không mở rộng và giàu tính năng, nhưng vẫn: Tôi không hiểu làm thế nào (tức là thông qua cơ chế nào) rất nhiều tính năng bổ sung (mà tôi có thể chưa kích hoạt) khiến một hệ thống như Visual Studio luôn cảm thấy chậm chạp khi so sánh.

Tôi muốn hỏi những người có kinh nghiệm làm việc với các hệ thống quy mô của Visual Studio: điều gì khiến họ chậm chạp? Đây có phải là các lớp dựa trên các lớp trừu tượng cần thiết để giữ cơ sở mã hóa trong khả năng hiểu của con người? Đây có phải là số lượng mã cần phải được chạy qua không? Có phải đó là xu hướng hiện đại đối với các phương pháp tiết kiệm thời gian của lập trình viên với chi phí (rất lớn) trong bộ phận sử dụng bộ nhớ / chu kỳ đồng hồ?


7
Đơn giản: khi khối lượng tăng, cần nhiều lực hơn để vượt qua quán tính.
Shog9

Ai đó đã từng nói với tôi những người quản lý nhưng tôi không tin điều đó.
Grassch MIchael

1
Đây là một phần lớn lý do tôi vẫn chủ yếu sử dụng D7 cho lập trình Delphi.
GrandmasterB

Mã nhanh nhất là không bao giờ được thực thi.
Henry

4
@romkyns: Tôi thấy nhiều phần mềm trong thời kỳ hiện đại thường vô cùng cồng kềnh, lớn không cần thiết và khó sử dụng. Rất nhiều phần mềm hiện đã giải quyết các vấn đề tương tự đã được giải quyết mười, thậm chí hai mươi năm trước, với một phần sức mạnh và không gian. Tại sao nó vẫn tụt hậu tệ như nó từng làm, nếu không muốn nói là như vậy? Không hiệu quả và phình to.
Orble

Câu trả lời:


20

Kiến trúc sư du hành vũ trụ

Visual Studio 2010 được xây dựng dựa trên Windows Presentation Foundation. Hãy xem lớp Nút cho WPF. Nó là con thứ 9 của một lớp cơ sở. Nó có khoảng 5 trang thuộc tính, phương pháp và sự kiện. Đằng sau hậu trường, nó có năm trang định nghĩa phong cách khác mô tả các góc tròn đẹp mắt của nó và chuyển động hoạt hình tinh tế khi một con trỏ chuột di chuyển qua nó. Đây là tất cả cho một cái gì đó về cơ bản hiển thị một số văn bản hoặc hình ảnh và tạo ra một sự kiện nhấp chuột khi nó phát hiện một nút chuột đi xuống.

Dừng một chương trình như Visual Studio tại bất kỳ điểm ngẫu nhiên nào. Nhìn vào dấu vết ngăn xếp. Rất có thể bạn đang ở 20 cấp độ sâu trong ngăn xếp cuộc gọi và năm DLL đã được tải để đến đó.

Bây giờ, so sánh hai điều này với Delphi. Tôi cá là bạn thấy rằng Nút Delphi chỉ có 20 thuộc tính, phương thức và sự kiện. Tôi cá rằng Delphi IDE chỉ có một dấu vết ngăn xếp sâu 5-7 cấp. Bởi vì khi máy tính hoạt động chậm hơn, bạn không thể sử dụng Visual Studio 2010 mà không cần IDE mất 40 phút để bắt đầu :-)

Cái này tốt hơn những cái khác phải không? Chà, tôi thường có thể nói với một chương trình Delphi khi nó tải vì nó trông phẳng, màu sắc bị tắt (có lẽ là 8 bit?), Và không có bóng mờ hoặc hoạt hình tinh tế. Tôi chỉ cảm thấy "rẻ" những ngày này. Rẻ, nhưng nhanh.

Chúng ta có tốt hơn không? Đó là một câu hỏi cho các nhà triết học, không phải các lập trình viên.


4
Một chương trình delphi không nhìn phẳng. Thay vào đó, một lập trình viên lập trình một chương trình để nhìn phẳng. Bạn có thể tạo giao diện đầy đủ màu sắc, hiện đại, đẹp mắt với Delphi giống như trong C # hoặc C ++.
GrandmasterB

2
Đây là một câu trả lời sâu sắc; nhưng tôi không chắc nó đã hoàn thành Visual Studio 2008 (tiền thân của năm 2010) không có WPF trong đó và vẫn chậm hơn Delphi 7. Bạn có còn nói điều tương tự về độ sâu ngăn xếp cuộc gọi và số lượng DLL được tải không?
Timwi

3
@Timwi Vâng, hoàn toàn tôi sẽ làm. Quan điểm của tôi là ít hơn về các tệ nạn của WPF (tôi thực sự thích WPF) và nhiều hơn về cách chúng ta có xu hướng thêm các lớp theo các lớp trừu tượng hóa khi được lựa chọn. Có lẽ Visual Studio 2008 không có quá nhiều chi phí, nhưng như bạn đã lưu ý, nó có khá đủ :-)
Jay Beavers

@GrandmasterB, tôi không nói xấu Delphi vì nó có ít giả định hơn và các thư viện đơn giản hơn. WPF được thiết kế giả định khả năng tăng tốc phần cứng GPU sẽ cho phép các chương trình sử dụng màu sắc sâu hơn, hoạt ảnh thường xuyên, pha trộn alpha, đổ bóng, v.v. Delphi được thiết kế tại thời điểm mà những giả định này không thể được thực hiện. Bạn có thể thực hiện lại tất cả điều này trong Delphi? Chắc chắn, nhưng bạn sẽ phải đặt rất nhiều mã hóa chỉ để có được hoạt động của nút WPF. Về mặt tích cực, nút Delphi không đi kèm với các yêu cầu về CPU, bộ nhớ và GPU, nút WPF có thể là câu hỏi của @ OP.
Jay Beavers

10
Đối số của bạn cho giao diện người dùng phẳng và đơn giản hoàn toàn bị vô hiệu hóa bởi giao diện người dùng 'Hiện đại' mới của Windows 10. Bây giờ chúng ta có tất cả chi phí đó để tạo ra các nút phẳng, vuông, trơn như chúng ta đã có 30 năm trước.
gbjbaanb

11

Tôi muốn hỏi những người có kinh nghiệm làm việc với các hệ thống quy mô của Visual Studio: điều gì khiến họ chậm chạp? Đây có phải là các lớp dựa trên các lớp trừu tượng cần thiết để giữ cơ sở mã hóa trong khả năng hiểu của con người? Đây có phải là số lượng mã cần phải được chạy qua không? Có phải đó là xu hướng hiện đại đối với các phương pháp tiết kiệm thời gian của lập trình viên với chi phí (rất lớn) trong bộ phận sử dụng bộ nhớ / chu kỳ đồng hồ?

Tôi nghĩ rằng bạn đã đoán được một số trong số họ nhưng tôi muốn đưa ra những gì tôi coi là yếu tố lớn nhất, đã làm việc trên một cơ sở mã lớn tương đối (không chắc là nó có lớn như Visual Studio không - nằm trong hàng triệu dòng mã loại và khoảng một nghìn plugin) trong khoảng 10 năm và quan sát hiện tượng xảy ra.

Nó cũng ít gây tranh cãi hơn vì nó không đi sâu vào API hoặc các tính năng ngôn ngữ hoặc bất cứ thứ gì tương tự. Những chi phí liên quan đến "chi phí" có thể tạo ra một cuộc tranh luận thay vì "chi tiêu" và tôi muốn tập trung vào "chi tiêu".

Phối hợp lỏng lẻo và di sản

Những gì tôi quan sát được là sự phối hợp lỏng lẻo và một di sản dài có xu hướng dẫn đến rất nhiều chất thải tích lũy.

Ví dụ, tôi tìm thấy khoảng một trăm cấu trúc tăng tốc trong cơ sở mã này, nhiều trong số chúng là dự phòng.

Chúng ta muốn có một cây KD để tăng tốc một động cơ vật lý, một cây khác cho một động cơ vật lý mới thường chạy song song với động cơ cũ, chúng ta có hàng tá các phép thực hiện cho các thuật toán lưới khác nhau, một cây KD khác để kết xuất , hái, v.v ... Đây đều là những cấu trúc cây to, cồng kềnh được sử dụng để tăng tốc tìm kiếm. Mỗi cá nhân có thể mất hàng trăm megabyte đến gigabyte bộ nhớ cho đầu vào có kích thước rất trung bình. Chúng không phải lúc nào cũng được khởi tạo và sử dụng mọi lúc, nhưng tại bất kỳ thời điểm nào, 4 hoặc 5 trong số chúng có thể nằm trong bộ nhớ cùng một lúc.

Bây giờ tất cả những thứ này đang lưu trữ cùng một dữ liệu để tăng tốc tìm kiếm cho chúng. Bạn có thể tưởng tượng nó giống như cơ sở dữ liệu cũ tương tự lưu trữ tất cả các trường của nó thành 20 bản đồ / từ điển dự phòng / cây B + dự phòng khác nhau cùng một lúc, được tổ chức giống hệt nhau và tìm kiếm tất cả chúng. Bây giờ chúng tôi đang chiếm 20 lần bộ nhớ và xử lý.

Ngoài ra, vì sự dư thừa, có ít thời gian để tối ưu hóa bất kỳ một trong số chúng với thẻ giá bảo trì đi kèm với điều đó, và ngay cả khi chúng tôi đã làm, nó sẽ chỉ có 5% hiệu quả lý tưởng.

Điều gì gây ra hiện tượng này? Phối hợp lỏng lẻo là nguyên nhân số một tôi thấy. Rất nhiều thành viên trong nhóm thường làm việc trong các hệ sinh thái biệt lập của họ, phát triển hoặc sử dụng cấu trúc dữ liệu của bên thứ ba, nhưng không sử dụng cùng cấu trúc mà các thành viên khác trong nhóm đang sử dụng ngay cả khi họ hoàn toàn trùng lặp với những mối quan tâm chính xác.

Điều gì gây ra hiện tượng này để tồn tại? Di sản và khả năng tương thích là nguyên nhân số một tôi thấy. Vì chúng tôi đã trả chi phí để thực hiện các cấu trúc dữ liệu này và một lượng lớn mã phụ thuộc vào các giải pháp này, nên thường rất rủi ro khi cố gắng hợp nhất chúng thành ít cấu trúc dữ liệu hơn. Mặc dù nhiều cấu trúc dữ liệu này rất dư thừa về mặt khái niệm, chúng không phải lúc nào cũng giống hệt nhau trong các thiết kế giao diện của chúng. Vì vậy, thay thế chúng sẽ là một thay đổi lớn, đầy rủi ro thay vì chỉ để chúng tiêu tốn bộ nhớ và thời gian xử lý.

Hiệu quả bộ nhớ

Thông thường, việc sử dụng bộ nhớ và tốc độ có xu hướng liên quan ở mức độ lớn nhất. Bạn thường có thể phát hiện ra phần mềm chậm bằng cách nó chiếm dụng bộ nhớ. Không phải lúc nào cũng có nhiều bộ nhớ dẫn đến chậm, vì vấn đề quan trọng là bộ nhớ "nóng" (bộ nhớ nào đang được truy cập mọi lúc - nếu một chương trình sử dụng một bộ nhớ thuyền nhưng chỉ sử dụng 1 megabyte thời gian, nó không phải là một vấn đề lớn về tốc độ).

Vì vậy, bạn có thể phát hiện ra những con lợn tiềm năng dựa trên việc sử dụng bộ nhớ rất nhiều thời gian. Nếu một ứng dụng cần hàng chục đến hàng trăm megabyte bộ nhớ khi khởi động, có lẽ nó sẽ không hiệu quả lắm. Hàng chục megabyte có vẻ nhỏ khi chúng ta có hàng gigabyte DRAM ngày nay, nhưng bộ nhớ CPU lớn nhất và chậm nhất vẫn nằm trong phạm vi megabyte, và nhanh nhất vẫn nằm trong phạm vi kilobyte. Kết quả là, một chương trình sử dụng 20 megabyte chỉ để khởi động và không làm gì thực sự vẫn sử dụng khá nhiều "bộ nhớ" từ quan điểm bộ nhớ cache của CPU phần cứng, đặc biệt là nếu tất cả 20 megabyte bộ nhớ đó sẽ được truy cập liên tục và thường xuyên như chương trình đang chạy.

Giải pháp

Đối với tôi, giải pháp là tìm kiếm các nhóm nhỏ hơn, phối hợp hơn để xây dựng sản phẩm, những nhóm có thể theo dõi "chi tiêu" của họ và tránh "mua" các mặt hàng tương tự lặp đi lặp lại.

Giá cả

Tôi sẽ nhúng vào khía cạnh "chi phí" gây tranh cãi hơn chỉ là một chút tuổi teen với hiện tượng "chi tiêu" mà tôi đã quan sát thấy. Nếu một ngôn ngữ kết thúc với một mức giá không thể tránh khỏi cho một đối tượng (như một ngôn ngữ cung cấp sự phản ánh thời gian chạy và không thể buộc phân bổ liên tục cho một loạt các đối tượng), thì thẻ giá đó chỉ đắt trong bối cảnh của một yếu tố rất chi tiết, như một đơn Pixelhoặc Boolean.

Tuy nhiên, tôi thấy rất nhiều mã nguồn cho các chương trình xử lý một tải nặng (ví dụ: xử lý hàng trăm nghìn đến hàng triệu Pixelhoặc các Booleantrường hợp) trả chi phí đó ở mức chi tiết như vậy.

Lập trình hướng đối tượng có thể làm trầm trọng thêm điều đó. Tuy nhiên, đó không phải là chi phí của "đối tượng" mỗi lần hoặc thậm chí OOP có lỗi, chỉ đơn giản là các chi phí đó được trả ở mức độ chi tiết của một yếu tố tuổi teen sẽ được hàng triệu người khởi tạo.

Vì vậy, đó là hiện tượng "chi phí" và "chi tiêu" khác mà tôi đang quan sát. Chi phí là một xu, nhưng đồng xu sẽ tăng thêm nếu chúng ta mua riêng một triệu lon soda thay vì đàm phán với nhà sản xuất để mua số lượng lớn.

Giải pháp ở đây với tôi là mua hàng "số lượng lớn". Các đối tượng hoàn toàn ổn ngay cả trong các ngôn ngữ có một số giá từng đồng xu với điều kiện là chi phí này không được trả riêng một triệu lần so với tương đương với một lon soda.

Tối ưu hóa sớm

Tôi chưa bao giờ thích từ ngữ mà Knuth sử dụng ở đây, bởi vì "tối ưu hóa sớm" hiếm khi làm cho các chương trình sản xuất trong thế giới thực diễn ra nhanh hơn. Một số người giải thích rằng "tối ưu hóa sớm" khi Knuth có nghĩa giống như "tối ưu hóa mà không có kiến ​​thức / kinh nghiệm phù hợp để biết tác động thực sự của nó đối với phần mềm". Nếu bất cứ điều gì, hiệu quả thực tế của tối ưu hóa sớm thực sự thường sẽ làm cho phần mềm chậm hơn , vì sự xuống cấp trong khả năng bảo trì có nghĩa là có ít thời gian để tối ưu hóa các đường dẫn quan trọng thực sự quan trọng .

Đây là hiện tượng cuối cùng tôi quan sát thấy, nơi các nhà phát triển tìm cách tiết kiệm từng đồng xu khi mua một lon soda, không bao giờ được mua nữa, hoặc tệ hơn, một ngôi nhà, đã lãng phí tất cả thời gian của họ (hoặc tệ hơn, đồng xu tưởng tượng từ không hiểu trình biên dịch của họ hoặc kiến ​​trúc của phần cứng) khi có hàng tỷ đô la bị lãng phí chi tiêu ở nơi khác.

Thời gian là rất hữu hạn vì vậy cố gắng tối ưu hóa tuyệt đối mà không có thông tin theo ngữ cảnh phù hợp thường làm mất cơ hội tối ưu hóa những nơi thực sự quan trọng, và do đó, về mặt hiệu quả thực tế, tôi sẽ nói rằng "tối ưu hóa sớm làm cho phần mềm chậm hơn nhiều. "

Vấn đề là có những kiểu nhà phát triển sẽ lấy những gì tôi đã viết ở trên về các đối tượng và cố gắng thiết lập một tiêu chuẩn mã hóa cấm lập trình hướng đối tượng hoặc một cái gì đó điên rồ kiểu đó. Tối ưu hóa hiệu quả là ưu tiên hiệu quả và hoàn toàn vô giá trị nếu chúng ta chìm đắm trong một biển các vấn đề bảo trì.


2
Nợ kỹ thuật, nói cách khác. Nợ kỹ thuật không bao giờ được trả hết.
Robert Harvey

1
Robert đã đúng. Một sai lầm từ một chàng trai, hai trăm lỗi --forced bởi các nhà quản lý hét lên "bạn sẽ bị sa thải nếu bạn không thực hiện điều này vào ngày mai", thổi bay nhiều năm thực hành kỹ thuật phần mềm tốt, TDD, kiểm thử đơn vị và bất kỳ nguyên tắc lập trình con người và lành mạnh nào , cộng với hai lần khác bạn mệt mỏi .. anh chàng đó đã khiến công ty phát điên vì anh ta bị cho nghỉ việc mà không có lý do gì và làm rối tung codebase .. những thư viện bị gián đoạn mà bạn không bao giờ cập nhật ... và ở đây bạn có nó: codebase ngon tuyệt và phần mềm cồng kềnh. Bon
ngon miệng

2
Thật thú vị, đặc biệt là cách bạn đã thấy mức độ chi tiết bị lạm dụng quá mức. Tôi đã bắt gặp bản thân mình làm điều gì đó tương tự trong quá khứ và kết quả kém. Điều này khá giống với câu trả lời của bạn từ vài ngày trước về việc sử dụng các bộ sưu tập và thuật toán số lượng lớn theo sở thích so với mức độ chi tiết quá mức . Tôi không thể tin rằng câu trả lời không được đánh giá cao hơn cho sự phong phú của nó. Nó khiến tôi suy nghĩ lại về một số thiết kế mà tôi đã xây dựng trong những năm qua. Tôi tự hỏi tại sao những kỹ thuật đó không được quảng bá rộng rãi hơn?
Mike hỗ trợ Monica

2
@Mike Tôi là một chút của một kỷ lục bị phá vỡ khi cố gắng thúc đẩy nhiều hơn một tư duy định hướng dữ liệu. Nó phổ biến trong ngành công nghiệp game nơi họ đang cố gắng tận dụng từng inch phần cứng. Điều đó nói rằng, nó thừa nhận làm giảm tính linh hoạt. Nếu bạn có một lớp pixel trừu tượng, bạn có thể làm những điều điên rồ với điều đó giống như có một hình ảnh duy nhất pha trộn hai hoặc nhiều định dạng pixel khác nhau! Tuy nhiên, khi chúng ta xử lý các đường dẫn quan trọng, có lẽ không có hình ảnh nào được hưởng lợi từ mức độ linh hoạt đó và hiệu suất bắt đầu trở thành mối quan tâm thực sự với bất kỳ thứ gì liên quan đến hình ảnh và pixel.

1
Trong những ngày xưa tồi tệ, tôi đã triển khai một số mã để bỏ qua các API đồ họa và truy cập trực tiếp các pixel trong bộ nhớ cho một đoạn mã quan trọng của mã. Sự khác biệt giữa nhiều lớp trừu tượng và truy cập trực tiếp là khoảng 100 lần, điều quan trọng trên máy tính trong những ngày đó. Bây giờ máy tính của bạn đủ nhanh để bạn có thể vượt qua bất kỳ số lượng trừu tượng nào, nếu bạn phải.
Michael Storesin
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.