2009-06-26 31 views
12

Sau ba năm làm việc trên một dự án C++, tệp thực thi đã tăng lên 4 MB. Tôi muốn nhìn thấy nơi mà tất cả không gian này đang diễn ra. Có một công cụ có thể báo cáo những con lợn không gian lớn nhất là gì? Nó sẽ được tốt đẹp để xem kích thước của lớp (tất cả các chức năng trong một lớp), bởi mẫu (tất cả các instantiations), và thư viện (bao nhiêu thuộc về thư viện tiêu chuẩn C và STL? Bao nhiêu cho mỗi thư viện trong exe?)Có một "hồ sơ kích thước chức năng" không?

Chỉnh sửa: Lưu ý, tôi đang sử dụng Visual C++ trên Windows.

+0

Trong trường hợp ai đó tự hỏi, hóa ra Flite (một công cụ chuyển văn bản thành giọng nói) là thành phần lớn nhất của 4 MB với tốc độ 1,8 MB IIRC, mà tôi đã phát hiện bằng cách xóa nó. – Qwertie

Trả lời

14

Trong Linux, bạn có thể sử dụng nm để hiển thị tất cả các biểu tượng trong thực thi và sắp xếp chúng theo thứ tự ngược lại theo kích thước:

$ nm -CSr --size-sort <exe> 

Options:

  • -C demangles C++ tên.
  • -S hiển thị kích thước biểu tượng.
  • --size-sort sắp xếp biểu tượng theo kích thước.
  • -r đảo ngược sắp xếp.

Nếu bạn muốn để có được những kết quả mỗi namespace hoặc mỗi lớp, bạn có thể chỉ grep đầu ra cho 'namespace::', 'namespace::class_name::', , vv.

Nếu bạn chỉ muốn xem các biểu tượng được xác định trong tệp thực thi (không được xác định ở nơi khác, như trong thư viện), sau đó thêm --defined-only. Sắp xếp theo kích thước nên cẩn thận vì điều này, vì các biểu tượng không xác định sẽ không có kích thước.

Đối với Windows, bạn vẫn sẽ có thể sử dụng nm trên các tập tin nhị phân của bạn, vì nm hỗ trợ COFF mã nhị phân. Bạn có thể cài đặt nm qua cygwin, hoặc bạn có thể sao chép các cửa sổ của bạn thực thi vào một hộp linux và chạy nm trên đó.

Bạn cũng có thể thử dumpbin, đưa ra thông tin về nhị phân trên Windows. Bạn có thể nhận thông tin về các biểu tượng bằng công tắc /SYMBOLS, nhưng có vẻ như nó không trực tiếp cung cấp thông tin về kích thước của chúng.

+0

Ahh, điều kỳ diệu của Linux. Nó quá tệ Tôi đang trên Windblows. – Qwertie

+0

bạn có thể biên dịch nó với gcc dưới Cygwin và sau đó sử dụng công cụ nm của nó cho một danh sách aproximate. – Blindy

+1

Theo như tôi biết, nm hỗ trợ COFF. Bạn chỉ có thể cài đặt nó thông qua Cygwin, hoặc bạn có thể sao chép exe sang một hộp Linux và chạy nm trên đó. Bạn cũng có thể thử tiện ích windows dumpbin. Xem ở đây: http://support.microsoft.com/?id=121460 – tgamblin

1

Nhận bản đồ liên kết hoặc sử dụng dumpbin để nhận danh sách các biểu tượng và kích thước.

Rất có thể có nhiều thứ bị kéo vào mà bạn không thực sự cần.

THÊM: Bạn có nhận được câu trả lời thỏa đáng không? Tôi nhận ra có hai cách mà mọi người tiếp cận các vấn đề như sau:

  • Lấy số đo trước khi thực hiện bất kỳ điều gì.
  • Chỉ cần tìm thứ gì đó to lớn mà họ không cần, tách ra và lặp lại cho đến khi không thể.

Cá nhân tôi thích thứ hai - kết quả sẽ nhanh hơn.

Bạn nói ứng dụng là 4MB. Giả sử kích thước thật cần thiết là 1MB (hoặc một số kích thước như vậy). Điều đó có nghĩa là nếu bạn chọn ngẫu nhiên một thường trình từ tệp bản đồ, có thể 75% là thứ bạn không cần. Tìm hiểu điều gì khiến nó được đưa vào và xem bạn có thực sự cần nó hay không.

Trong ví dụ bạn đã cung cấp, bạn đã thấy một lớp kết thúc tốt các bitmap không phụ thuộc vào thiết bị. Bạn có thể tìm thấy các cá thể của lớp đó trong ứng dụng của bạn và có thể thay thế chúng bằng các bitmap WIN32 cơ bản. Nó sẽ ít đẹp hơn, nhưng tiết kiệm gobs kích thước ứng dụng.

Sau đó tiếp tục làm việc đó. Mỗi phần lớn bạn có được thoát khỏi làm cho phần còn lại mất một tỷ lệ phần trăm lớn hơn của ứng dụng, bởi vì các ứng dụng đã bị thu hẹp nhưng các mảnh đã không. Điều đó giúp chúng dễ dàng tìm thấy trong tệp bản đồ.

+0

Lấy ví dụ về trình bao bọc DIB một lần nữa, lớp đó có thể nhỏ và tôi có thể không lưu bất cứ thứ gì bằng cách tách nó ra. OTOH, có lẽ có rất nhiều trường hợp khác nhau của vector , bản đồ , hash_map, vv và có lẽ tôi muốn tiết kiệm không gian bằng cách tìm cách để chia sẻ trường hợp. Nhưng sau đó một lần nữa, có lẽ trình biên dịch đủ thông minh để hợp nhất các siêu trình giống hệt nhau (có thể xảy ra thường xuyên với các khuôn mẫu) hoặc có thể các lớp đó không chiếm nhiều không gian mặc dù nhiều trường hợp. Có lẽ nếu tôi có dữ liệu tốt, tôi sẽ không thể tiết kiệm được không gian nào, hoặc không gian đó sẽ đến những nơi bất ngờ. – Qwertie

+0

Tôi biết từ kinh nghiệm của mình với các trình biên dịch "bình thường" mà trực giác của tôi về nguồn tài nguyên thường đi sai. Vì vậy, nó không đủ để chỉ thực hiện một kiểm tra trực quan của một tập tin .map và chỉ đơn giản là đoán các lớp/chức năng/thư viện mất rất nhiều phòng. – Qwertie

+0

@Qwertie: Tôi biết ý bạn là gì, nhưng nếu có rất nhiều tài nguyên tồn tại vì một lý do kém, hãy lấy mẫu tài nguyên một cách thưa thớt và xác định lý do đằng sau mỗi mẫu, có thể tiết lộ vấn đề. Bạn không có cái gì đó đo lường chính xác nhưng cho chút thấu triệt. Bạn cần một cái gì đó mà các biện pháp thô nhưng cung cấp cho cái nhìn sâu sắc tối đa. –

7

Trong Windows trong biên dịch Visual Studio, thông tin này nằm trong tệp .map của bạn (nó sẽ ở gần tệp .pdb).

ADDED: Để chuyển đổi tên trang trí được tìm thấy trong tệp .map thành một cái gì đó dễ đọc hơn, bạn có thể sử dụng tiện ích undname.exe đi kèm với Visual Studio. Nó chấp nhận các tên riêng lẻ trên dòng lệnh hoặc bạn có thể cho nó một tệp .map.

Ví dụ,

Microsoft (R) C++ Name Undecorator 
Copyright (C) Microsoft Corporation. All rights reserved. 

Undecoration of "[email protected][email protected][email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@Z" is 

"public: void __cdecl mini_vector<struct Math::Point<struct Math::FixedPoint<14,int> >,6>::push_back(struct Math::Point<struct Math::FixedPoint<14,int> > const &)" 
+2

Tôi nhìn vào tập tin bản đồ của tôi, và không thực sự nhìn thấy dòng như thế nào như "0001:??? 0000f380 push_back @ $ mini_vector @ U $ Point @ U $ FixedPoint @ $ 0o @ H @ Math Math @@@ @@ $ 05 @@ QAAXABU? $ Điểm @ U? $ FixedPoint @ $ 0O @ H @ Toán @@@ Math @@@ Z 10010380 fi dibitmapsce: DIBitmap.obj "rất hữu ích cho việc lập hồ sơ. – Qwertie

+0

Không được đưa ra bởi các tên bị xé. Điều đó nói rằng trong hỗ trợ bitmap độc lập thiết bị có một chức năng để phụ thêm vào cuối của một vectơ điểm, và nó ở địa chỉ F380 (62336) trong phân đoạn 1. Tôi đặt cược có rất nhiều thứ giống như nó. Bạn có thể xem để xem nơi này được tham chiếu, và nếu không cần thiết, xem bạn có thể thoát khỏi nó. –

+0

Bạn có thể undecorate tên với undname.exe, được tìm thấy trong thư mục thùng Visual Studio của bạn; chạy phím tắt "Visual Studio 200X Command Prompt" sẽ đặt nó vào% PATH% của bạn. Hoặc nếu bạn muốn làm cho họ với số lượng lớn, tôi thấy kịch bản Python này mà hiện nó tự động: http://holycall.tistory.com/entry/A-Simple-Python-Wrapper-to-Undecorate-Visual-Studio-Linker- Symbol-Names – Crashworks

1

Đừng chỉ nhìn vào mã - nguồn lực có thể dễ dàng gây ra sự phát triển đa megabyte.

+0

Đúng vậy - bitmap & như vậy có thể đồ sộ. –

+0

May mắn là kích thước bitmap dễ đo - và không phải là vấn đề trong trường hợp của tôi. – Qwertie

2

Tôi không thể nhận được nm để làm việc cho tôi nhưng đã quản lý để tìm một công cụ hữu ích được gọi là Sizer. Nó đọc thông tin gỡ lỗi được tạo ra bởi Visual Studio bằng cách sử dụng các thư viện Debug Interface Access. Nó khá đơn giản để sử dụng, như mô tả trên trang web.

  1. Compile với gỡ lỗi thông tin trong cơ sở dữ liệu chương trình (PDB) nộp
  2. Run sizer từ dòng lệnh ví dụ Sizer.exe <path-to-exe-file>. Đầu ra sẽ chuyển sang chế độ stdout để bạn có thể muốn chuyển hướng đến một tệp.

Kích thước mã được chia nhỏ theo các phần khác nhau và được nhóm theo chức năng, dữ liệu, lớp, v.v ..., mỗi phần được sắp xếp theo thứ tự mã giảm dần.

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