2011-05-28 31 views
9

Chúng tôi đã phát triển một ứng dụng tài chính lớn tại một ngân hàng. Nó bắt đầu là 150k dòng mã thực sự xấu. Bởi 1 tháng trước, nó đã giảm xuống còn hơn một nửa, nhưng kích thước của tập tin thực thi vẫn còn rất lớn. Tôi hy vọng rằng khi chúng tôi chỉ làm cho mã dễ đọc hơn, nhưng mã templated vẫn còn tạo ra rất nhiều mã đối tượng, chúng tôi đã chỉ được hiệu quả hơn với nỗ lực của chúng tôi.thực thi rất lớn vì các biểu tượng gỡ lỗi, tại sao?

Ứng dụng được chia thành khoảng 5 đối tượng được chia sẻ và một đối tượng chính. Một trong những đối tượng chia sẻ lớn hơn là 40Mb và tăng lên 50 ngay cả khi mã bị thu hẹp.

Tôi không hoàn toàn ngạc nhiên khi mã bắt đầu phát triển, bởi vì sau khi tất cả chúng tôi đang thêm một số chức năng. Nhưng tôi đã ngạc nhiên rằng nó đã tăng 20%. Chắc chắn không có ai đến gần bằng văn bản 20% mã, vì vậy thật khó cho tôi để tưởng tượng nó phát triển như thế nào nhiều. Mô-đun đó rất khó phân tích, nhưng vào thứ Sáu, tôi có một điểm dữ liệu mới cho thấy một số ánh sáng.

Có thể có 10 nguồn cấp dữ liệu cho máy chủ SOAP. Mã được tự động phát hiện. Mỗi dịch vụ có một lớp trình phân tích cú pháp có cùng mã chính xác, giống như sau:

#include <boost/shared_ptr.hpp> 
#include <xercesstuff...> 
class ParserService1 { 
public: 
    void parse() { 
    try { 
     Service1ContentHandler*p = new Service1ContentHandler(...); 
     parser->setContentHandler(p); 
     parser->parser(); 
    } catch (SAX ...) { 
     ... 
    } 
    } 
}; 

Các lớp này hoàn toàn không cần thiết, một hàm hoạt động. Mỗi lớp ContentHandler đã được tạo tự động với cùng 7 hoặc 8 biến, mà tôi có thể chia sẻ với thừa kế.

Vì vậy, tôi đã mong đợi kích thước của mã giảm xuống khi tôi xóa các lớp trình phân tích cú pháp và tất cả từ mã. Nhưng chỉ với 10 dịch vụ, tôi đã không mong đợi nó giảm từ 38Mb xuống 36Mb. Đó là một số lượng lớn các biểu tượng. Điều duy nhất tôi có thể nghĩ là mỗi phân tích cú pháp bao gồm tăng :: shared_ptr, một số công cụ phân tích cú pháp Xerces, và bằng cách nào đó, trình biên dịch và trình liên kết lưu trữ tất cả các ký hiệu đó lặp lại cho mỗi tệp. Tôi tò mò muốn tìm hiểu trong mọi trường hợp.

Vì vậy, bất cứ ai có thể đề xuất cách tôi sẽ đi về việc theo dõi lý do tại sao một sửa đổi đơn giản như thế này sẽ có tác động rất nhiều? Tôi có thể sử dụng nm trên một mô-đun để nhìn vào các biểu tượng bên trong, nhưng điều đó sẽ tạo ra một lượng lớn các công cụ bán dễ đọc.

Ngoài ra, khi một đồng nghiệp chạy mã của cô ấy bằng thư viện mới của tôi, thời gian của người dùng đã tăng từ 1m55 giây lên 1m25 giây. Thời gian thực là rất khác nhau, bởi vì chúng tôi đang chờ đợi trên các máy chủ SOAP chậm (IMHO, SOAP là một thay thế vô cùng nghèo cho CORBA ...) nhưng thời gian CPU là khá ổn định. Tôi đã có thể mong đợi một chút tăng từ việc giảm kích thước mã nhiều, nhưng điểm mấu chốt là, trên một máy chủ với bộ nhớ lớn, tôi đã thực sự ngạc nhiên rằng tốc độ đã bị ảnh hưởng rất nhiều, xem xét tôi đã không thay đổi kiến ​​trúc của Tự xử lý XML.

Tôi sẽ tiến xa hơn vào thứ ba và hy vọng sẽ nhận được nhiều thông tin hơn, nhưng nếu có ai đó có ý tưởng về cách tôi có thể cải thiện nhiều điều này, tôi rất muốn biết.

Cập nhật: Tôi xác minh rằng trên thực tế, việc gỡ lỗi biểu tượng trong tác vụ dường như không thay đổi thời gian chạy. Tôi đã làm điều này bằng cách tạo một tệp tiêu đề bao gồm rất nhiều nội dung, bao gồm cả hai tệp có tác dụng ở đây: tăng các con trỏ được chia sẻ và một số trình phân tích cú pháp XML xerces. Dường như không có hiệu suất thời gian chạy (tôi đã kiểm tra vì có sự khác biệt về ý kiến ​​giữa hai câu trả lời). Tuy nhiên, tôi cũng xác minh rằng bao gồm các tệp tiêu đề tạo các biểu tượng gỡ lỗi cho từng trường hợp, mặc dù kích thước nhị phân bị tước không thay đổi. Vì vậy, nếu bạn bao gồm một tệp nhất định, ngay cả khi bạn thậm chí không sử dụng nó, có một số biểu tượng cố định phản đối đối tượng đó không được gấp lại với nhau tại thời gian liên kết mặc dù chúng có lẽ giống hệt nhau.

Mã của tôi trông giống như:

#include "includetorture.h" 
void f1() 
{ 
    f2(); // call the function in the next file 
} 

Kích thước với riêng tôi bao gồm các file khoảng 100k mỗi nguồn tập tin. Có lẽ, nếu tôi đã bao gồm nhiều hơn, nó sẽ cao hơn. Tổng số thực thi với các bao gồm là ~ 600k, mà không có khoảng 9k. Tôi đã xác minh rằng sự tăng trưởng là tuyến tính với số lượng tệp đang thực hiện bao gồm, nhưng mã bị tước có cùng kích thước bất kể, vì nó phải như vậy.

Rõ ràng tôi đã nhầm tưởng rằng đây là lý do để đạt được hiệu suất. Tôi nghĩ rằng tôi đã chiếm được điều đó ngay bây giờ. Mặc dù tôi không loại bỏ nhiều mã, nhưng tôi đã sắp xếp rất nhiều quy trình xử lý chuỗi xml lớn và giảm đường dẫn thông qua mã đáng kể và đó có thể là lý do.

+0

cảm ơn chỉnh sửa Magnus! – Dov

+0

Trong tiêu đề của bạn, bạn đề cập đến các biểu tượng gỡ lỗi, nhưng bạn không nằm trong phần còn lại của bài đăng. Tui bỏ lỡ điều gì vậy? – Bart

+0

@Bart Các bloat là vì tất cả các biểu tượng gỡ lỗi trong thực thi. Nếu bạn loại bỏ các thư viện, mã là khoảng 10% kích thước. – Dov

Trả lời

5

Bạn có thể sử dụng tiện ích đọc trên linux hoặc dumpbin trên cửa sổ để tìm số lượng không gian chính xác được sử dụng bởi các loại dữ liệu khác nhau trong tệp exe. Mặc dù, tôi không thấy lý do tại sao kích thước thực thi là đáng lo ngại bạn: gỡ lỗi các biểu tượng sử dụng TUYỆT ĐỐI KHÔNG có bộ nhớ tại thời gian chạy!

+1

rõ ràng, chỉ cần tạo ra khối lượng công cụ đó mất thời gian khi xây dựng. Tôi lo ngại về xu hướng này. Đây là, giảm kích thước mã, và thực thi có thể tăng lên 20%. Đó là tốt để biết mặc dù, rằng họ không được nạp vào thời gian chạy .... – Dov

+1

C + + biểu tượng trở nên điên rồ dài vì mangling tên; điều này đặc biệt rõ ràng khi sử dụng boost. Một loại dường như "đơn giản", chẳng hạn như sự khởi tạo của một số mẫu tăng, có thể tạo ra các tên bị xé có độ dài ít kB! Trong những trường hợp như vậy, kích thước của thông tin gỡ lỗi bị chi phối bởi NUMBER đối tượng khác nhau (phương thức, hàm, mẫu được tạo). Đó là một vấn đề được biết đến, và một số thư viện tăng địa chỉ giảm chiều dài tên biểu tượng trong hướng dẫn sử dụng của họ. Nhưng, một lần nữa, tại sao bạn đang cố gắng giảm kích thước mã? – zvrba

+1

Tôi quan tâm vì tôi nhận thấy rằng sắp xếp hợp lý vài trăm dòng mã không cần có nhiều tác động đến hệ thống tổng thể có ảnh hưởng to lớn về tổng kích thước ký hiệu và hiệu suất của ứng dụng. Nếu tôi có thể nhận ra những gì đang gây ra sưng lên và biết làm thế nào để tránh nó, nhiệm vụ sẽ chạy khá nhanh hơn một chút. Đây không phải là một vấn đề tầm thường, vì chúng ta phải chạy trong sản xuất với gỡ lỗi (để mã có thể được gỡ lỗi nếu có vấn đề) và nếu tôi có thể đạt được tốc độ thắng, nó là tổng thể, thuận lợi cho cả thử nghiệm và hàng đêm của chúng ta batch – Dov

2

Dường như bạn đang sử dụng rất nhiều lớp C++ với các phương thức nội tuyến. Nếu các lớp này có khả năng hiển thị cao, mã nội tuyến này sẽ làm nổi bật toàn bộ ứng dụng. Tôi đặt cược thời gian liên kết của bạn đã tăng lên là tốt. Hãy thử giảm số lượng các phương thức nội tuyến và di chuyển mã sang tệp .cpp. Điều này sẽ làm giảm kích thước của các tệp đối tượng của bạn, tệp exe và giảm thời gian liên kết.

Giao dịch trong trường hợp này dĩ nhiên là giảm kích thước đơn vị biên dịch, so với thời gian thực hiện.

+0

Nếu đó là xerces và tăng cường, tôi không chắc chắn tôi muốn chỉnh sửa nội dung của họ, nhưng tôi sẽ xem xét. – Dov

+0

Nếu mã được gạch chân và không được gọi, sẽ không có hiệu lực. Tôi nghi ngờ điều này là do các biến toàn cục và kéo tất cả các ký hiệu mà chúng tham chiếu đến. Nhưng tôi không biết tại sao mối liên kết giữ nhiều bản sao trong tệp thực thi - có lẽ quá đắt để loại bỏ chúng. – Dov

+0

Chắc chắn, nhưng mã nội tuyến sẽ tạo mã trong nhiều đơn vị thực thi (trên một số tệp đối tượng) mà nếu không được tối ưu hóa sẽ làm tăng kết quả thực thi.Hãy nhớ rằng mã nội tuyến là nội tuyến và giao dịch tắt (luôn có giao dịch tắt) là thời gian thực hiện nhanh hơn so với phí gọi hàm. – ralphtheninja

2

Tôi không có câu trả lời rất mong đợi cho câu hỏi của bạn, nhưng hãy để tôi chia sẻ kinh nghiệm của mình.

Điều khá phổ biến là sự khác biệt về kích thước của tệp thực thi là rất cao. Tôi không thể giải thích lý do tại sao chi tiết, nhưng chỉ nghĩ về tất cả những điều điên rồ mà những kẻ lừa đảo hiện đại cho phép bạn thực hiện trên mã của mình. Bạn biết đấy, điều này là nhờ vào các biểu tượng gỡ lỗi.

Sự khác biệt về kích thước quá lớn đến mức nếu bạn đang tải một cách tự động một số thư viện được chia sẻ, thì thời gian tải tệp tuyệt đối có thể giải thích sự khác biệt về hiệu suất bạn tìm thấy. Thật vậy, đây là một khía cạnh khá "nội bộ" của trình biên dịch, và chỉ để cung cấp cho bạn một ví dụ, năm trở lại tôi đã khá không hài lòng với các tập tin thực thi lớn mà GCC-4 sản xuất so với GCC-3, sau đó tôi đơn giản là đã quen với nó (và HD của tôi cũng tăng kích thước).

Tất cả trong tất cả, tôi sẽ không nhớ, bởi vì bạn có nghĩa vụ phải sử dụng xây dựng với các biểu tượng gỡ lỗi chỉ trong quá trình phát triển, nơi mà nó không phải là một vấn đề. Trong triển khai, không có biểu tượng gỡ lỗi chỉ ở đó và bạn sẽ thấy số lượng tệp sẽ thu nhỏ.

+0

sergio, sau khi thử nghiệm, điều này có vẻ không đúng. Kích thước thực thi không có gì để làm với tốc độ, ít nhất là trong thử nghiệm nhỏ tôi đã làm. Và điều này không phải ngẫu nhiên, tôi có thể làm một thử nghiệm, và nó có thể lặp lại, nếu khó chịu. – Dov

+0

@Dov, cảm ơn bạn đã kiểm tra điều này. Thực ra ý tôi là * thời gian tải *. Nếu bạn có một số thư viện được chia sẻ, mỗi thư viện có kích thước 10MB và có đầy đủ các biểu tượng và bạn tải chúng một cách linh động, thời điểm bạn tải chúng, chương trình của bạn sẽ chậm lại do liên kết động. Nếu bạn đếm mười sự chậm lại, bạn có thể nhận được một cái gì đó đáng chú ý. Nhưng đó chỉ là một ý tưởng, vì tôi không biết ứng dụng của bạn được kiến ​​trúc như thế nào. Dù sao, vì bạn đã loại bỏ các tệp thi hành, tôi hiểu rằng thời gian tải cũng không ảnh hưởng đến ứng dụng của bạn. – sergio

+0

thử nghiệm của tôi là tất nhiên trên các tập tin nhỏ hơn nhiều, nhưng chúng tôi đang nói về một công việc lớn với thời gian chạy là 10 phút, vì vậy ngay cả khi nó đã được tải trong vài giây, 100Mb sẽ không có nhiều tác dụng như trong thực tế, nó đã không. – Dov

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