Có phải sự thay đổi dần dần trong phương pháp viết mã ảnh hưởng đến hiệu năng hệ thống? Và tôi có nên quan tâm?


35

TD; DR:

Có một số nhầm lẫn về những gì tôi đã hỏi, vì vậy đây là ý tưởng lái xe đằng sau câu hỏi:

Tôi luôn dự định câu hỏi là gì Tôi có thể không nói rõ nó ban đầu. Nhưng mục đích luôn luôn là " là mô-đun, tách rời, ghép lỏng, tách rời, mã tái cấu trúc " chậm hơn rõ rệt bởi bản chất của nó so với " đơn vị nguyên khối, làm mọi thứ ở một nơi, một tệp, được ghép chặt chẽ ". Phần còn lại chỉ là chi tiết và các biểu hiện khác nhau về điều này mà tôi đã gặp sau đó hoặc bây giờ hoặc sẽ sau này. Đó là chậm hơn cho chắc chắn trên một số quy mô. Giống như một đĩa không phân mảnh, bạn phải nhặt các mảnh từ khắp mọi nơi. Nó chậm hơn. Chắc chắn. Nhưng tôi có nên quan tâm?

Và câu hỏi không phải là về ...

không phải về tối ưu hóa vi mô, tối ưu hóa sớm, v.v. Nó không phải là "tối ưu hóa phần này hay phần kia cho đến chết".

Sau đó là gì?

Đó là về phương pháp tổng thể và các kỹ thuật và cách suy nghĩ về việc viết mã xuất hiện theo thời gian:

  • "tiêm mã này vào lớp của bạn như là một phụ thuộc"
  • "viết một tệp cho mỗi lớp"
  • "tách quan điểm của bạn khỏi cơ sở dữ liệu, bộ điều khiển, tên miền của bạn".
  • không viết speblock đồng nhất spaghetti, nhưng viết nhiều thành phần mô-đun riêng biệt làm việc cùng nhau

Đó là về cách thức và phong cách của mã hiện tại - trong thập kỷ này - được thấy và ủng hộ trong hầu hết các khuôn khổ, được ủng hộ tại các công ước, được truyền qua cộng đồng. Đó là một sự thay đổi trong suy nghĩ từ 'khối nguyên khối' sang 'microservice'. Và cùng với đó là giá cả về hiệu năng và chi phí cấp máy, và một số chi phí cấp lập trình viên là tốt.

Câu hỏi gốc sau:

Trong lĩnh vực Khoa học Máy tính, tôi đã nhận thấy một sự thay đổi đáng chú ý trong suy nghĩ khi nói đến lập trình. Tôi bắt gặp những lời khuyên khá thường xuyên như thế này:

  • viết mã nhỏ hơn chức năng (có thể kiểm tra và duy trì theo cách này)
  • tái cấu trúc mã hiện có thành các đoạn mã nhỏ hơn và nhỏ hơn cho đến khi hầu hết các phương thức / hàm của bạn chỉ dài vài dòng và rõ ràng mục đích của chúng là gì (tạo ra nhiều hàm hơn, so với khối nguyên khối lớn hơn)
  • viết các hàm chỉ làm một việc - tách các mối quan tâm, v.v (thường tạo ra nhiều hàm hơn và nhiều khung hơn trên một ngăn xếp)
  • tạo nhiều tệp hơn (một lớp trên mỗi tệp, nhiều lớp hơn cho mục đích phân tách, cho các mục đích lớp như MVC, kiến ​​trúc miền, mẫu thiết kế, OO, v.v., tạo ra nhiều lệnh gọi hệ thống tệp hơn)

Đây là một sự thay đổi so với các thực hành mã hóa "cũ" hoặc "lỗi thời" hoặc "spaghetti" trong đó bạn có các phương thức trải dài 2500 dòng, và các lớp lớn và các đối tượng thần làm mọi thứ.

Câu hỏi của tôi là:

khi nó gọi đến mã máy, đến 1 và 0, để hướng dẫn lắp ráp, cho các đĩa cứng, tôi nên lo lắng rằng mã OO được phân tách hoàn hảo của lớp tôi với nhiều hàm và phương thức từ nhỏ đến nhỏ được tái cấu trúc thêm nhiều chi phí?

Chi tiết

Mặc dù tôi không quen thuộc lắm với cách mã OO và các lệnh gọi phương thức của nó được xử lý trong ASM cuối cùng, và cách các cuộc gọi và trình biên dịch DB gọi dịch chuyển sang cánh tay truyền động trên đĩa cứng, tôi có một số ý tưởng. Tôi giả sử rằng mỗi cuộc gọi chức năng bổ sung, cuộc gọi đối tượng hoặc cuộc gọi "#include" (trong một số ngôn ngữ), tạo ra một bộ hướng dẫn bổ sung, từ đó tăng âm lượng mã và thêm các chi phí "nối dây mã" khác nhau, mà không cần thêm mã "hữu ích" thực tế . Tôi cũng tưởng tượng rằng tối ưu hóa tốt có thể được thực hiện cho ASM trước khi nó thực sự được chạy trên phần cứng, nhưng tối ưu hóa đó chỉ có thể làm được rất nhiều.

Do đó, câu hỏi của tôi - bao nhiêu chi phí (trong không gian và tốc độ) không phân tách tốt mã (mã được phân chia trên hàng trăm tệp, lớp và mẫu thiết kế, v.v.) thực sự giới thiệu so với "một phương thức lớn có chứa tất cả mọi thứ trong một tập tin nguyên khối ", do chi phí này?

CẬP NHẬT cho rõ ràng:

Tôi giả định rằng việc lấy cùng một mã và tách nó, tái cấu trúc nó ra, tách nó thành ngày càng nhiều hàm và các đối tượng và các phương thức và các lớp sẽ dẫn đến ngày càng nhiều tham số truyền giữa các đoạn mã nhỏ hơn. Bởi vì chắc chắn, mã tái cấu trúc phải giữ cho luồng hoạt động và điều đó đòi hỏi phải truyền tham số. Nhiều phương thức hoặc nhiều lớp hơn hoặc nhiều mẫu thiết kế Phương thức nhà máy hơn, dẫn đến việc truyền nhiều thông tin khác nhau nhiều hơn so với trường hợp trong một lớp hoặc phương thức nguyên khối duy nhất.

Người ta đã nói ở đâu đó (trích dẫn TBD) rằng có tới 70% tất cả mã được tạo thành từ lệnh MOV của ASM - tải các thanh ghi CPU với các biến thích hợp, chứ không phải tính toán thực tế. Trong trường hợp của tôi, bạn tải lên thời gian của CPU bằng các hướng dẫn PUSH / POP để cung cấp liên kết và tham số truyền giữa các đoạn mã khác nhau. Bạn càng tạo ra các đoạn mã càng nhỏ thì càng cần nhiều "liên kết". Tôi lo ngại rằng mối liên kết này làm tăng sự phình to và chậm chạp của phần mềm và tôi tự hỏi liệu tôi có nên lo lắng về điều này không, và bao nhiêu, nếu có, bởi vì các thế hệ lập trình viên hiện tại và tương lai đang xây dựng phần mềm cho thế kỷ tiếp theo , sẽ phải sống với và tiêu thụ phần mềm được xây dựng bằng cách sử dụng các thực tiễn này.

CẬP NHẬT: Nhiều tập tin

Tôi đang viết mã mới bây giờ đang dần thay thế mã cũ. Đặc biệt tôi đã lưu ý rằng một trong các lớp cũ là tệp dòng ~ 3000 (như đã đề cập trước đó). Bây giờ nó đang trở thành một tập hợp 15-20 tệp nằm trên các thư mục khác nhau, bao gồm các tệp thử nghiệm và không bao gồm khung PHP mà tôi đang sử dụng để liên kết một số thứ với nhau. Nhiều tập tin đang đến là tốt. Khi nói đến I / O đĩa, tải nhiều tệp chậm hơn tải một tệp lớn. Tất nhiên không phải tất cả các tệp đều được tải, chúng được tải khi cần, và các tùy chọn bộ nhớ đệm và bộ nhớ đệm tồn tại, nhưng tôi vẫn tin rằng loading multiple filescần nhiều xử lý hơn loading a single filevào bộ nhớ. Tôi đang thêm điều đó vào mối quan tâm của tôi.

CẬP NHẬT: Phụ thuộc Tiêm mọi thứ

Trở lại vấn đề này sau một thời gian .. Tôi nghĩ rằng câu hỏi của tôi đã bị hiểu lầm. Hoặc có thể tôi đã chọn để hiểu sai một số câu trả lời. Tôi không nói về tối ưu hóa vi mô vì một số câu trả lời đã được nêu ra, (ít nhất tôi nghĩ gọi những gì tôi đang nói về tối ưu hóa vi mô là một cách hiểu sai), nhưng về sự chuyển động của "Mã tái cấu trúc để nới lỏng khớp nối" , ở mọi cấp độ của mã. Tôi đến từ Zend Con gần đây, nơi phong cách mã này là một trong những điểm cốt lõi và trung tâm của hội nghị. Phân tách logic từ chế độ xem, chế độ xem từ mô hình, mô hình từ cơ sở dữ liệu và nếu bạn có thể, hãy tách dữ liệu khỏi cơ sở dữ liệu. Sự phụ thuộc - Tiêm mọi thứ, đôi khi có nghĩa là chỉ cần thêm mã dây (chức năng, lớp, bản tóm tắt) mà không làm gì cả, nhưng phục vụ như một điểm nối / móc, dễ dàng nhân đôi kích thước mã trong hầu hết các trường hợp.

CẬP NHẬT 2: Việc "tách mã thành nhiều tệp" có ảnh hưởng đáng kể đến hiệu suất (ở tất cả các cấp độ tính toán)

Làm thế nào để triết lý compartmentalize your code into multiple filestác động của điện toán ngày nay (hiệu suất, sử dụng đĩa, quản lý bộ nhớ, xử lý CPU)?

tôi đang nói về

Trước...

Trong một quá khứ giả định nhưng khá thực tế không quá xa, bạn có thể dễ dàng viết một khối đơn của một tệp có mô hình và chế độ xem và điều khiển spaghetti hoặc không mã hóa spaghetti, nhưng nó chạy mọi thứ một khi nó đã được tải. Thực hiện một số điểm chuẩn trong quá khứ bằng cách sử dụng mã C Tôi phát hiện ra rằng việc tải một tệp 900Mb vào bộ nhớ và xử lý nó thành nhiều phần lớn hơn so với tải các tệp nhỏ hơn và xử lý chúng trong một bữa ăn nhỏ hơn nhanh hơn chunk làm cùng một công việc cuối cùng.

.. Và bây giờ*

Hôm nay tôi thấy mình đang xem mã hiển thị một sổ cái, có các tính năng như .. nếu một mục là "đơn hàng", hãy hiển thị khối HTML đơn hàng. Nếu một mục hàng có thể được sao chép, hãy in khối HTML hiển thị biểu tượng và tham số HTML phía sau nó cho phép bạn tạo bản sao. Nếu mục có thể được di chuyển lên hoặc xuống, hiển thị các mũi tên HTML thích hợp. V.v. Tôi có thể, thông qua Zend Framework tạopartial()các cuộc gọi, về cơ bản có nghĩa là "gọi một hàm lấy tham số của bạn và chèn chúng vào một tệp HTML riêng mà nó cũng gọi". Tùy thuộc vào mức độ chi tiết tôi muốn nhận, tôi có thể tạo các hàm HTML riêng cho các phần nhỏ nhất của sổ cái. Một cho mũi tên lên, mũi tên xuống, một cho "tôi có thể sao chép mục này", v.v ... Dễ dàng tạo một số tệp chỉ để hiển thị một phần nhỏ của trang web. Lấy mã của tôi và mã Zend Framework phía sau hậu trường, hệ thống / ngăn xếp có thể gọi gần 20-30 tệp khác nhau.

Gì?

Tôi quan tâm đến các khía cạnh, sự hao mòn trên máy được tạo ra bằng cách sắp xếp mã thành nhiều tệp riêng biệt nhỏ hơn.

Ví dụ, tải nhiều tệp hơn có nghĩa là đặt chúng ở nhiều vị trí khác nhau của hệ thống tệp và ở nhiều nơi khác nhau của ổ cứng vật lý, điều đó có nghĩa là thời gian tìm và đọc nhiều ổ cứng hơn.

Đối với CPU, nó có thể có nghĩa là chuyển đổi ngữ cảnh nhiều hơn và tải các thanh ghi khác nhau.

Trong khối phụ này (bản cập nhật # 2) tôi quan tâm nghiêm ngặt hơn về cách sử dụng nhiều tệp để thực hiện cùng một tác vụ có thể được thực hiện trong một tệp duy nhất, ảnh hưởng đến hiệu suất hệ thống.

Sử dụng API biểu mẫu Zend so với HTML đơn giản

Tôi đã sử dụng API biểu mẫu Zend với các thực tiễn OO hiện đại và mới nhất, để xây dựng một biểu mẫu HTML có xác thực, chuyển đổi POSTthành các đối tượng miền.

Tôi phải mất 35 tập tin để thực hiện.

35 files = 
    = 10 fieldsets x {programmatic fieldset + fieldset manager + view template} 
    + a few supporting files

Tất cả có thể được thay thế bằng một vài tệp HTML + PHP + JS + CSS đơn giản, có thể có tổng cộng 4 tệp trọng lượng nhẹ.

Có tốt hơn không Có đáng không? ... Hãy tưởng tượng tải 35 tệp + nhiều tệp thư viện Zend Zramework làm cho chúng hoạt động, so với 4 tệp đơn giản.


1
Câu hỏi tuyệt vời. Tôi sẽ làm một số điểm chuẩn (đưa tôi một ngày hoặc lâu hơn để tìm một số trường hợp tốt). Tuy nhiên, cải tiến tốc độ ở mức độ này có chi phí rất lớn cho khả năng đọc và chi phí phát triển. Dự đoán ban đầu của tôi là kết quả là hiệu suất tăng không đáng kể.
Dan Sabin

7
@Dan: Bạn có thể vui lòng đặt nó trong lịch của bạn để điểm chuẩn mã sau 1, 5 và 10 năm bảo trì. Nếu tôi nhớ tôi sẽ kiểm tra lại kết quả :)
mattnz

1
Phải đó là kicker thực sự. Tôi nghĩ rằng tất cả chúng ta đồng ý thực hiện ít tra cứu và các cuộc gọi chức năng nhanh hơn. Tuy nhiên tôi không thể tưởng tượng ra một trường hợp được ưu tiên cho những thứ như duy trì và dễ dàng đào tạo thành viên nhóm mới.
Dan Sabin

2
Để làm rõ bạn có yêu cầu tốc độ cụ thể cho dự án của bạn. Hay bạn chỉ muốn mã của mình "đi nhanh hơn!" Nếu đó là cái sau tôi sẽ không lo lắng về nó, mã đủ nhanh nhưng dễ bảo trì tốt hơn nhiều so với mã nhanh hơn đủ nhanh nhưng lại là một mớ hỗn độn.
Cormac Mulhall

4
Ý tưởng tránh các lời kêu gọi chức năng vì lý do hiệu suất chính xác là kiểu suy nghĩ điên rồ mà Dijkstra đã phản đối trong câu nói nổi tiếng của ông về tối ưu hóa trước khi trưởng thành. Nghiêm túc mà nói, tôi không thể
RibaldEddie

Câu trả lời:


10

Câu hỏi của tôi là: khi nó gọi mã máy, đến 1 và 0, theo hướng dẫn lắp ráp, tôi có nên lo lắng rằng mã được phân tách lớp của tôi với nhiều hàm nhỏ đến nhỏ tạo ra quá nhiều chi phí không?

Câu trả lời của tôi là có, bạn nên. Không phải vì bạn có rất nhiều chức năng nhỏ (ngày xưa, chức năng gọi điện có ý nghĩa hợp lý và bạn có thể làm chậm chương trình của mình bằng cách thực hiện một triệu cuộc gọi nhỏ trong các vòng lặp, nhưng ngày nay các trình biên dịch sẽ thực hiện chúng cho bạn và những gì còn lại được thực hiện quan tâm đến các thuật toán dự đoán ưa thích của CPU, vì vậy đừng lo lắng về điều đó) nhưng bởi vì bạn sẽ đưa ra khái niệm phân lớp quá nhiều vào các chương trình của mình khi chức năng quá nhỏ để có thể tự mò mẫm trong đầu. Nếu bạn có các thành phần lớn hơn, bạn có thể chắc chắn rằng chúng không thực hiện cùng một công việc lặp đi lặp lại, nhưng bạn có thể làm cho chương trình của mình trở nên nhỏ đến mức bạn có thể thấy mình không thể thực sự hiểu các đường dẫn cuộc gọi, và cuối cùng có một cái gì đó mà hầu như không hoạt động (và hầu như không thể bảo trì).

Ví dụ, tôi làm việc tại một nơi chỉ cho tôi một dự án tham khảo cho một dịch vụ web với 1 phương thức. Dự án bao gồm 32 tệp .cs - cho một dịch vụ web! Tôi nhận ra rằng điều này quá phức tạp, mặc dù mỗi phần đều nhỏ bé và dễ hiểu, khi nói đến việc mô tả toàn bộ hệ thống, tôi nhanh chóng thấy mình phải lần theo các cuộc gọi chỉ để xem nó đang làm cái quái gì (ở đó cũng có quá nhiều trừu tượng liên quan, như bạn mong đợi). Dịch vụ web thay thế của tôi là 4 tệp .cs.

Tôi đã không đo lường hiệu suất như tôi nghĩ nó sẽ gần như giống nhau trong tất cả, nhưng tôi có thể đảm bảo rằng giá của tôi rẻ hơn đáng kể để duy trì. Khi mọi người nói về thời gian lập trình viên quan trọng hơn thời gian của CPU, sau đó tạo ra những con quái vật phức tạp tốn rất nhiều thời gian của lập trình viên trong cả nhà phát triển và bảo trì, bạn phải tự hỏi rằng họ đang kiếm cớ cho hành vi xấu.

Người ta đã nói ở đâu đó (trích dẫn TBD) rằng có tới 70% tất cả mã được tạo thành từ lệnh MOV của ASM - tải các thanh ghi CPU với các biến thích hợp, chứ không phải tính toán thực tế.

Đó những gì CPU làm, mặc dù chúng di chuyển các bit từ bộ nhớ sang các thanh ghi, thêm hoặc bớt chúng, sau đó đưa chúng trở lại bộ nhớ. Tất cả các máy tính sôi xuống khá nhiều đó. Nhắc bạn, tôi đã từng có một chương trình rất đa luồng dành phần lớn thời gian để chuyển đổi ngữ cảnh (nghĩa là lưu và khôi phục trạng thái thanh ghi của các luồng) so với khi nó hoạt động trên mã luồng. Một khóa đơn giản ở sai vị trí thực sự làm hỏng hiệu suất ở đó, và nó cũng là một đoạn mã vô hại.

Vì vậy, lời khuyên của tôi là: tìm một trung dung hợp lý giữa một trong hai cực đoan làm cho mã của bạn trông tốt cho người khác và kiểm tra hệ thống để xem nó có hoạt động tốt không. Sử dụng các tính năng của HĐH để đảm bảo nó chạy như bạn mong đợi với CPU, bộ nhớ, đĩa và IO mạng.


Tôi nghĩ rằng điều này nói nhiều nhất với tôi ngay bây giờ. Nó gợi ý cho tôi rằng một nền tảng tốt là bắt đầu với các khái niệm ánh xạ tâm trí đến các đoạn mã trong khi theo dõi và sử dụng các khái niệm nhất định (như DI), thay vì gắn liền với phân tách mã bí truyền và thực hiện mọi thứ cho dù bạn cần Nó hay không).
Dennis

1
Cá nhân, tôi thấy rằng mã "" hiện đại "hơn có phần dễ cấu hình hơn ... Tôi đoán rằng một đoạn mã càng dễ bảo trì thì cũng dễ cấu hình hơn, nhưng có một giới hạn, trong đó việc phá vỡ mọi thứ thành các mảnh nhỏ làm cho chúng ít bảo trì hơn ...
AK_

25

Không có sự quan tâm cao độ, tối ưu hóa vi mô như những mối quan tâm này dẫn đến mã không thể nhầm lẫn.

Ban đầu có vẻ như là một ý tưởng tốt, trình hồ sơ cho bạn biết mã nhanh hơn và V & V / Test / QA thậm chí còn nói rằng hoạt động. Lỗi sớm được tìm thấy, yêu cầu thay đổi và cải tiến mà không bao giờ được xem xét được yêu cầu.

Trong vòng đời của một mã dự án xuống cấp và trở nên kém hiệu quả hơn. Mã duy trì sẽ trở nên hiệu quả hơn so với đối tác không thể nhầm lẫn của nó vì nó sẽ xuống cấp chậm hơn. Lý do là mã xây dựng entropy khi nó được thay đổi -

Mã không thể nhận biết nhanh chóng có nhiều mã chết hơn, đường dẫn dư thừa và trùng lặp. Điều này dẫn đến nhiều lỗi hơn, tạo ra một chu kỳ xuống cấp của mã - bao gồm cả hiệu năng của nó. Trước đó, các nhà phát triển có độ tin cậy thấp rằng những thay đổi họ đang thực hiện là chính xác. Điều này làm họ chậm lại, làm cho sự thận trọng và thường dẫn đến thậm chí nhiều entropy hơn khi họ chỉ giải quyết các chi tiết họ có thể nhìn thấy

Mã duy trì, với các mô-đun nhỏ và kiểm tra đơn vị dễ thay đổi hơn, mã không còn cần thiết sẽ dễ xác định và loại bỏ hơn. Mã bị hỏng cũng dễ xác định hơn, có thể được sửa chữa hoặc thay thế bằng sự tự tin.

Cuối cùng, nó đi xuống quản lý vòng đời và không đơn giản vì "cái này nhanh hơn nên nó sẽ luôn nhanh hơn."

Trên tất cả, mã chính xác chậm là vô cùng nhanh hơn mã nhanh không chính xác.


Cảm ơn Để hướng điều này một chút về nơi tôi sẽ đến, tôi không nói về tối ưu hóa vi mô, mà là một động thái toàn cầu hướng tới việc viết mã nhỏ hơn, kết hợp nhiều phép tiêm phụ thuộc hơn và do đó có nhiều phần chức năng bên ngoài hơn và nói chung là "các phần chuyển động" của mã rằng tất cả cần phải được kết nối với nhau để họ làm việc. Tôi có xu hướng nghĩ rằng điều này tạo ra nhiều liên kết / kết nối / biến-chuyền / MOV / PUSH / POP / CALL / JMP ở cấp độ phần cứng. Tôi cũng thấy một giá trị thay đổi theo hướng dễ đọc mã, mặc dù phải trả giá bằng việc hy sinh các chu kỳ tính toán ở mức phần cứng cho "lông tơ".
Dennis

10
Tránh các cuộc gọi chức năng vì lý do hiệu suất hoàn toàn là một tối ưu hóa vi mô! Nghiêm túc. Tôi không thể nghĩ ra một ví dụ tốt hơn về tối ưu hóa vi mô. Bạn có bằng chứng nào cho thấy sự khác biệt về hiệu năng thực sự quan trọng đối với loại phần mềm mà bạn đang viết? Có vẻ như bạn không có bất kỳ.
RibaldEddie

17

Theo hiểu biết của tôi, như bạn chỉ ra với nội tuyến, ở các dạng mã cấp thấp hơn như C ++, nó có thể tạo ra sự khác biệt nhưng tôi nói CÓ THỂ nhẹ.

Trang web tổng hợp nó - không có câu trả lời dễ dàng . Nó phụ thuộc vào hệ thống, nó phụ thuộc vào ứng dụng của bạn đang làm gì, nó phụ thuộc vào ngôn ngữ, nó phụ thuộc vào trình biên dịch và tối ưu hóa.

C ++ chẳng hạn, nội tuyến có thể tăng hiệu suất. Nhiều lần nó có thể không làm gì, hoặc có thể làm giảm hiệu suất nhưng cá nhân tôi chưa bao giờ gặp phải điều đó mặc dù bản thân tôi đã nghe về những câu chuyện. Inline không có gì khác hơn là một gợi ý cho trình biên dịch để tối ưu hóa, có thể bỏ qua.

Rất có thể, nếu bạn đang phát triển các chương trình cấp cao hơn, thì không nên lo lắng nếu có một chương trình bắt đầu. Trình biên dịch cực kỳ thông minh ngày nay và dù sao cũng nên xử lý công cụ này. Nhiều lập trình viên có mã để sống bằng cách: đừng bao giờ tin vào trình biên dịch. Nếu điều này áp dụng cho bạn, thì ngay cả những tối ưu hóa nhỏ mà bạn cảm thấy cũng quan trọng. Nhưng, hãy nhớ, mọi ngôn ngữ đều khác nhau về vấn đề này. Java thực hiện tối ưu hóa nội tuyến tự động khi chạy. Trong Javascript, nội tuyến cho trang web của bạn (trái ngược với các tệp riêng biệt) là một sự tăng cường và mỗi giây trong một trang web có thể được tính nhưng đó là vấn đề IO nhiều hơn.

Nhưng ở các chương trình cấp thấp hơn, nơi lập trình viên có thể làm rất nhiều mã máy hoạt động cùng với một cái gì đó như C ++, việc nghe lỏm có thể tạo ra sự khác biệt. Các trò chơi là một ví dụ điển hình về việc đường ống CPU rất quan trọng, đặc biệt là trên các bảng điều khiển và một cái gì đó như nội tuyến có thể tăng thêm một chút ở đây và ở đó.

Một cách đọc tốt về nội tuyến cụ thể: http://www.gotw.ca/gotw/033.htm


Xuất phát từ quan điểm của câu hỏi của tôi, tôi không tập trung vào nội tuyến mỗi seh, mà là "hệ thống dây được mã hóa" chiếm CPU, bus 'và quá trình thời gian của I / O liên kết các đoạn mã khác nhau. Tôi tự hỏi nếu có một số điểm có 50% hoặc nhiều hơn mã dây và 50% mã thực tế bạn muốn chạy. Tôi tưởng tượng có rất nhiều lông tơ ngay cả trong mã chặt chẽ nhất mà người ta có thể viết, và nó dường như là một thực tế của cuộc sống. Phần lớn mã thực tế chạy ở cấp độ bit và byte là hậu cần - di chuyển các giá trị từ nơi này sang nơi khác, nhảy đến nơi này hay nơi khác và đôi khi chỉ thực hiện thêm ..
Dennis

... Phép trừ hoặc chức năng liên quan đến kinh doanh khác. Giống như việc hủy đăng ký vòng lặp có thể tăng tốc một số vòng lặp do ít chi phí được phân bổ cho các biến tăng dần, việc viết các hàm lớn hơn có thể có thể thêm một số tốc độ, miễn là trường hợp sử dụng của bạn được thiết lập cho nó. Mối quan tâm của tôi ở đây là tổng thể hơn, nhìn thấy nhiều lời khuyên để viết các đoạn mã nhỏ hơn, tăng hệ thống dây điện này, trong khi có lợi cho việc thêm khả năng đọc (hy vọng) và chi phí phình to ở cấp độ vi mô.
Dennis

3
@Dennis - một điều cần xem xét là trong ngôn ngữ OO, có thể có RẤT ít mối tương quan giữa những gì lập trình viên viết (a + b) và mã nào được tạo ra (một đơn giản thêm hai thanh ghi? Di chuyển từ bộ nhớ trước? sau đó hàm gọi vào toán tử của đối tượng +?). Vì vậy, 'các hàm nhỏ' ở cấp độ của lập trình viên có thể là bất cứ thứ gì ngoại trừ nhỏ khi được kết xuất thành mã máy.
Michael Kohne

2
@Dennis Tôi có thể nói rằng viết mã ASM (trực tiếp, không được biên dịch) cho Windows đi theo dòng "Mov, Mov, invoke, Mov, Mov, invoke". Với việc gọi là một macro thực hiện cuộc gọi được bao bọc bởi các lần nhấn / bật ... Đôi khi, bạn sẽ thực hiện các cuộc gọi chức năng trong mã của riêng mình nhưng nó bị lấn át bởi tất cả các cuộc gọi của hệ điều hành.
Brian Knoblauch

12

Đây là một thay đổi so với các thực tiễn mã "cũ" hoặc "xấu" trong đó bạn có các phương thức trải rộng 2500 dòng và các lớp lớn làm mọi thứ.

Tôi không nghĩ bất cứ ai từng nghĩ rằng làm điều đó là một thực hành tốt. Và tôi nghi ngờ những người đã làm nó vì lý do hiệu suất.

Tôi nghĩ rằng câu nói nổi tiếng từ Donald Knuth rất phù hợp ở đây:

Chúng ta nên quên đi những hiệu quả nhỏ, nói về 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi.

Vì vậy, trong 97% mã của bạn, chỉ cần sử dụng các thực tiễn tốt, viết các phương thức nhỏ (vấn đề nhỏ như thế nào, tôi không nghĩ tất cả các phương thức chỉ là vài dòng), v.v. Đối với 3% còn lại, trong đó hiệu suất không quan trọng, đo lường nó. Và nếu các phép đo cho thấy rằng có nhiều phương thức nhỏ thực sự làm chậm mã của bạn một cách đáng kể, thì bạn nên kết hợp chúng thành các phương thức lớn hơn. Nhưng đừng viết mã không thể nhầm lẫn chỉ vì nó thể nhanh hơn.


11

Bạn cần cẩn thận lắng nghe các lập trình viên có kinh nghiệm cũng như suy nghĩ hiện tại. Những người đã xử lý nhiều năm với phần mềm lớn có một cái gì đó để đóng góp.

Theo kinh nghiệm của tôi, đây là những gì dẫn đến sự chậm lại, và chúng không hề nhỏ. Chúng là những mệnh lệnh có độ lớn:

  • Giả định rằng bất kỳ dòng mã nào cũng mất nhiều thời gian như bất kỳ dòng nào khác. Ví dụ cout << endlso với a = b + c. Cái trước mất hàng ngàn lần lâu hơn cái trước. Stackexchange có rất nhiều câu hỏi thuộc dạng "Tôi đã thử các cách khác nhau để tối ưu hóa mã này, nhưng dường như nó không tạo ra sự khác biệt, tại sao không?" khi có một hàm lớn gọi ở giữa nó.

  • Giả định rằng bất kỳ chức năng hoặc phương thức gọi, một khi được viết, tất nhiên là cần thiết. Các chức năng và phương thức rất dễ gọi và cuộc gọi thường khá hiệu quả. Vấn đề là chúng giống như thẻ tín dụng. Họ cám dỗ bạn chi tiêu nhiều hơn bạn thực sự muốn, và họ có xu hướng che giấu những gì bạn đã chi tiêu. Trên hết, phần mềm lớn có các lớp trừu tượng, do đó, ngay cả khi chỉ có 15% chất thải ở mỗi lớp, trên 5 lớp kết hợp với hệ số làm chậm là 2. Câu trả lời cho điều này là không loại bỏ chức năng hoặc viết chức năng lớn hơn, đó là kỷ luật bản thân để cảnh giác với vấn đề này và sẵn sàng và có thể khắc phục nó .

  • Phi nước đại. Giá trị của sự trừu tượng là nó có thể cho phép bạn làm được nhiều hơn với ít mã hơn - ít nhất đó là hy vọng. Ý tưởng này có thể được đẩy đến cực đoan. Vấn đề với quá nhiều tính tổng quát là mọi vấn đề đều cụ thể và khi bạn giải quyết nó bằng những tóm tắt chung, những trừu tượng đó không nhất thiết có thể khai thác các thuộc tính cụ thể của vấn đề của bạn. Ví dụ, tôi đã thấy một tình huống trong đó một lớp xếp hàng ưu tiên ưa thích, có thể hiệu quả ở kích thước lớn, được sử dụng khi độ dài không bao giờ vượt quá 3!

  • Cấu trúc dữ liệu phi mã. OOP là một mô hình rất hữu ích, nhưng nó không khuyến khích người ta giảm thiểu cấu trúc dữ liệu - thay vào đó nó khuyến khích người ta cố gắng che giấu sự phức tạp của nó. Ví dụ, có khái niệm "thông báo" trong đó nếu dữ liệu A được sửa đổi theo một cách nào đó, A đưa ra một sự kiện thông báo để B và C cũng có thể tự sửa đổi để giữ cho toàn bộ tập hợp nhất quán. Điều này có thể lan truyền trên nhiều lớp và chi phí rất lớn cho việc sửa đổi. Sau đó, hoàn toàn có thể thay đổi thành A có thể ngay sau đó được hoàn táchoặc thay đổi thành một sửa đổi khác, có nghĩa là nỗ lực dành cho việc cố gắng duy trì sự đồng nhất phải được thực hiện lại. Điều đáng lo ngại là xác suất xảy ra lỗi trong tất cả các trình xử lý thông báo và tính tuần hoàn, v.v. Tốt hơn hết là cố gắng giữ cấu trúc dữ liệu được chuẩn hóa, để chỉ có bất kỳ thay đổi nào được thực hiện ở một nơi. Nếu dữ liệu không được chuẩn hóa không thể tránh được, tốt hơn là nên có các lần định kỳ để sửa chữa sự không nhất quán, thay vì giả vờ nó có thể được giữ phù hợp với một dây xích ngắn.

... khi tôi nghĩ về nhiều hơn tôi sẽ thêm nó.


8

Câu trả lời ngắn gọn là có". Và, nói chung, mã sẽ chậm hơn một chút.

Nhưng đôi khi, một cấu trúc lại OO-ish thích hợp sẽ tiết lộ các tối ưu hóa giúp mã nhanh hơn. Tôi đã làm việc trên một dự án nơi chúng tôi tạo ra một thuật toán Java phức tạp hơn nhiều OO-ish, với các cấu trúc dữ liệu, getters, v.v. thay vì các mảng đối tượng lồng nhau lộn xộn. Nhưng, bằng cách cách ly và hạn chế truy cập tốt hơn vào các cấu trúc dữ liệu, chúng tôi đã có thể thay đổi từ các mảng Nhân đôi khổng lồ (với null cho kết quả trống) thành các mảng nhân đôi có tổ chức hơn, với NaN cho kết quả trống. Điều này mang lại tốc độ tăng gấp 10 lần.

Phụ lục: Nói chung, mã nhỏ hơn, có cấu trúc tốt hơn nên dễ điều chỉnh hơn cho đa luồng, cách tốt nhất của bạn để có được sự tăng tốc lớn.


1
Tôi không thấy lý do tại sao việc chuyển đổi từ Doubles sang doubles yêu cầu mã có cấu trúc tốt hơn.
Svick

Wow, một downvote? Mã khách hàng ban đầu không giao dịch với Double.NaN, nhưng đang kiểm tra null để thể hiện các giá trị trống. Sau khi tái cấu trúc, chúng ta có thể xử lý việc này (thông qua đóng gói) với các getters của các kết quả thuật toán khác nhau. Chắc chắn, chúng tôi có thể đã viết lại mã máy khách, nhưng điều này dễ dàng hơn.
dùng949300

Đối với hồ sơ, tôi không phải là người đánh giá thấp câu trả lời này.
Svick

7

Trong số những thứ khác, lập trình là về sự đánh đổi . Dựa trên thực tế này, tôi có khuynh hướng trả lời có, nó có thể chậm hơn. Nhưng hãy nghĩ về những gì bạn nhận được. Nhận mã dễ đọc, có thể tái sử dụng và dễ dàng sửa đổi dễ dàng vượt qua mọi nhược điểm có thể có.

Như @ user949300 đã đề cập , sẽ dễ dàng hơn để phát hiện các khu vực có thể được cải thiện về mặt thuật toán hoặc kiến ​​trúc với cách tiếp cận như vậy; cải thiện những người thường được nhiều lợi và hiệu quả hơn so với việc không có khả năng OO hoặc hàm gọi overhead (mà đã là chỉ một tiếng động, tôi đặt cược).


Tôi cũng tưởng tượng rằng tối ưu hóa tốt có thể được thực hiện cho ASM trước khi nó thực sự được chạy trên phần cứng.

Bất cứ khi nào điều gì đó thích điều này xuất hiện trong đầu tôi, tôi nhớ rằng hàng thập kỷ dành cho những người thông minh nhất làm việc trên trình biên dịch có lẽ đang tạo ra các công cụ như GCC tốt hơn nhiều so với tôi trong việc tạo mã máy. Trừ khi bạn đang làm việc trên một số loại công cụ liên quan đến vi điều khiển, tôi khuyên bạn không nên lo lắng về điều đó.

Tôi giả định rằng việc thêm càng nhiều hàm và càng nhiều đối tượng và lớp trong mã sẽ dẫn đến ngày càng nhiều tham số chuyển giữa các đoạn mã nhỏ hơn.

Giả sử bất cứ điều gì khi tối ưu hóa là lãng phí thời gian, bạn cần sự thật về hiệu suất mã. Tìm nơi bạn lập trình dành phần lớn thời gian với các công cụ chuyên dụng, tối ưu hóa điều đó, lặp đi lặp lại.


Tổng hợp tất cả lên; hãy để trình biên dịch thực hiện công việc của nó, tập trung vào những thứ quan trọng như cải thiện thuật toán và cấu trúc dữ liệu của bạn. Tất cả các mẫu bạn đề cập trong câu hỏi của bạn tồn tại để giúp bạn với điều đó, sử dụng chúng.

Tái bút: Hai cuộc nói chuyện của Crockford đã xuất hiện trong đầu tôi và tôi nghĩ chúng có liên quan đến nhau. Đầu tiên là lịch sử CS siêu ngắn gọn (luôn luôn tốt để biết với bất kỳ khoa học chính xác nào); và thứ hai là về lý do tại sao chúng ta từ chối những điều tốt đẹp.


Tôi thực sự thích câu trả lời này nhất. Con người thật kinh khủng khi đoán thứ hai trình biên dịch và chụp ảnh tại nơi tắc nghẽn. tất nhiên độ phức tạp thời gian lớn là điều bạn nên chú ý, nhưng phương pháp spaghetti 100 dòng lớn so với lời gọi phương thức nhà máy + một số phương thức ảo gửi thậm chí không bao giờ nên là một cuộc thảo luận. hiệu suất không phải là thú vị trong trường hợp đó. Ngoài ra, điểm cộng lớn cho việc lưu ý rằng "tối ưu hóa" mà không có sự thật và đo lường cứng là một sự lãng phí thời gian.
sara

4

Tôi tin rằng các xu hướng bạn xác định điểm ở một sự thật về phát triển phần mềm - thời gian lập trình viên đắt hơn thời gian CPU. Cho đến nay, máy tính chỉ trở nên nhanh hơn và rẻ hơn, nhưng một mớ hỗn độn của một ứng dụng có thể mất hàng trăm nếu không phải hàng ngàn giờ để thay đổi. Với chi phí tiền lương, lợi ích, không gian văn phòng, v.v., sẽ hiệu quả hơn khi có mã có thể thực thi chậm hơn một chút nhưng thay đổi nhanh hơn và an toàn hơn.


1
Tôi đồng ý, nhưng thiết bị di động đang trở nên phổ biến đến mức tôi nghĩ rằng chúng là một ngoại lệ lớn. Mặc dù sức mạnh xử lý đang tăng lên, bạn không thể xây dựng một ứng dụng iPhone và hy vọng có thể thêm bộ nhớ như bạn có thể trên máy chủ web.
JeffO

3
@JeffO: Tôi không đồng ý - Các thiết bị di động có bộ xử lý lõi tứ hiện nay là bình thường, hiệu năng (đặc biệt là nó ảnh hưởng đến tuổi thọ pin), trong khi một mối quan tâm, ít quan trọng hơn sự ổn định. Một điện thoại di động hoặc máy tính bảng chậm bị đánh giá kém, một cái không ổn định sẽ bị tàn sát. Các ứng dụng di động rất năng động, thay đổi gần như hàng ngày - nguồn phải theo kịp.
mattnz

1
@JeffO: Đối với những gì đáng giá, máy ảo được sử dụng trên Android khá tệ. Theo điểm chuẩn, nó có thể là một thứ tự cường độ chậm hơn mã gốc (trong khi loại tốt nhất của giống thường chỉ chậm hơn một chút). Đoán xem, không ai quan tâm. Viết ứng dụng rất nhanh và CPU nằm đó xoay tròn ngón tay cái và chờ người dùng nhập 90% thời gian.
Jan Hudec

Có nhiều hiệu năng hơn so với điểm chuẩn CPU thô. Điện thoại Android của tôi hoạt động tốt, ngoại trừ khi AV đang quét một bản cập nhật và sau đó nó dường như chỉ bị treo lâu hơn tôi muốn, và đó là mẫu RAM 2Gb lõi tứ! Ngày nay băng thông (dù là mạng hay bộ nhớ) có lẽ là nút cổ chai chính. CPU siêu tốc của bạn có thể gấp đôi ngón tay cái 99% thời gian và trải nghiệm tổng thể vẫn còn kém.
gbjbaanb

4

Hơn 20 năm trước, tôi đoán bạn không gọi mới và không "cũ hay xấu", quy tắc là giữ cho các chức năng đủ nhỏ để vừa trên một trang in. Sau đó, chúng tôi đã có máy in ma trận điểm, do đó, số lượng dòng đã được sửa chữa thường chỉ có một hoặc hai lựa chọn cho số dòng trên mỗi trang ... chắc chắn ít hơn 2500 dòng.

Bạn đang hỏi nhiều khía cạnh của vấn đề, khả năng bảo trì, hiệu suất, khả năng kiểm tra, khả năng đọc. Bạn càng nghiêng về hiệu suất, mã sẽ càng dễ bảo trì và dễ đọc hơn, vì vậy bạn phải tìm mức độ thoải mái có thể và sẽ thay đổi cho từng lập trình viên riêng lẻ.

Theo như mã được tạo bởi trình biên dịch (mã máy nếu bạn muốn), hàm càng lớn thì càng có nhiều cơ hội cần phải đổ các giá trị trung gian trong các thanh ghi vào ngăn xếp. Khi khung stack được sử dụng, mức tiêu thụ stack nằm trong khối lớn hơn. Các hàm càng nhỏ thì càng có nhiều cơ hội cho dữ liệu lưu lại nhiều hơn trong các thanh ghi và càng ít phụ thuộc vào ngăn xếp. Khối nhỏ hơn của ngăn xếp cần thiết cho mỗi chức năng một cách tự nhiên. Khung stack có ưu và nhược điểm cho hiệu suất. Nhiều chức năng nhỏ hơn có nghĩa là thiết lập chức năng và dọn dẹp nhiều hơn. Tất nhiên nó cũng phụ thuộc vào cách bạn biên dịch, cơ hội nào bạn cung cấp cho trình biên dịch. Bạn có thể có 250 hàm 10 dòng thay vì một hàm 2500 dòng, một hàm 2500 dòng mà trình biên dịch sẽ có nếu nó có thể / chọn để tối ưu hóa toàn bộ. Nhưng nếu bạn lấy 250 hàm 10 dòng đó và trải chúng ra 2, 3, 4, 250 tệp riêng biệt, biên dịch từng tệp riêng biệt thì trình biên dịch sẽ không thể tối ưu hóa gần như nhiều mã chết như nó có thể có. điểm mấu chốt ở đây là có những ưu và nhược điểm cho cả hai và không thể đưa ra một quy tắc chung về điều này hoặc đó là cách tốt nhất.

Các chức năng có kích thước hợp lý, thứ mà một người có thể nhìn thấy trên màn hình hoặc trang (trong một phông chữ hợp lý), là thứ họ có thể tiêu thụ tốt hơn và hiểu hơn mã khá lớn. Nhưng nếu đó chỉ là một chức năng nhỏ với các cuộc gọi đến nhiều chức năng nhỏ khác gọi nhiều chức năng nhỏ khác, bạn cần một số cửa sổ hoặc trình duyệt để hiểu mã đó, do đó bạn không mua bất cứ thứ gì ở phía dễ đọc.

cách unix là sử dụng thuật ngữ của tôi, các khối lego được đánh bóng độc đáo. Tại sao bạn sẽ sử dụng chức năng băng này nhiều năm sau khi chúng tôi ngừng sử dụng băng? Bởi vì blob đã làm rất tốt công việc của mình và ở mặt sau, chúng tôi có thể thay thế giao diện băng bằng giao diện tệp và tận dụng lợi thế của chương trình. Tại sao lại viết phần mềm ghi đĩa cdrom chỉ vì scsi biến mất khi giao diện chiếm ưu thế được thay thế bằng ide (sau đó sẽ quay lại sau). Một lần nữa hãy tiến hành các khối phụ được đánh bóng và thay thế một đầu bằng một khối giao diện mới (cũng hiểu các nhà thiết kế phần cứng chỉ đơn giản là xử lý một khối giao diện trên các thiết kế phần cứng để trong một số trường hợp làm cho một ổ đĩa scsi có giao diện ide thành scsi. , xây dựng các khối lego đánh bóng có kích thước hợp lý, mỗi khối có mục đích được xác định rõ ràng và đầu vào và đầu ra được xác định rõ. bạn có thể bọc các bài kiểm tra xung quanh các khối lego đó và sau đó lấy cùng một khối và bọc giao diện người dùng và giao diện hệ điều hành xung quanh cùng một khối và khối, theo lý thuyết đã được kiểm tra tốt và hiểu rõ không cần phải gỡ lỗi, chỉ cần thêm các khối mới được thêm vào trên mỗi đầu. miễn là tất cả các giao diện khối của bạn được thiết kế tốt và chức năng được hiểu rõ, bạn có thể xây dựng rất nhiều thứ tuyệt vời với tối thiểu nếu có keo. giống như với các khối lego màu xanh và đỏ và đen và vàng với kích thước và hình dạng đã biết, bạn có thể tạo ra nhiều thứ tuyệt vời. miễn là tất cả các giao diện khối của bạn được thiết kế tốt và chức năng được hiểu rõ, bạn có thể xây dựng rất nhiều thứ tuyệt vời với tối thiểu nếu có keo. giống như với các khối lego màu xanh và đỏ và đen và vàng với kích thước và hình dạng đã biết, bạn có thể tạo ra nhiều thứ tuyệt vời. miễn là tất cả các giao diện khối của bạn được thiết kế tốt và chức năng được hiểu rõ, bạn có thể xây dựng rất nhiều thứ tuyệt vời với tối thiểu nếu có keo. giống như với các khối lego màu xanh và đỏ và đen và vàng với kích thước và hình dạng đã biết, bạn có thể tạo ra nhiều thứ tuyệt vời.

Mỗi cá nhân là khác nhau, định nghĩa của họ về đánh bóng và xác định rõ và kiểm tra và có thể đọc khác nhau. Chẳng hạn, không phải là vô lý khi một giáo sư ra lệnh cho các quy tắc lập trình không phải vì chúng có thể hoặc không tệ đối với bạn như một chuyên gia, nhưng trong một số trường hợp để làm cho công việc đọc và chấm điểm mã của bạn dễ dàng hơn đối với giáo sư hoặc trợ lý sinh viên tốt nghiệp ... Về mặt chuyên môn, bạn có thể thấy rằng mỗi công việc có thể có các quy tắc khác nhau vì nhiều lý do khác nhau, thường là một hoặc một vài người nắm quyền có ý kiến ​​về điều gì đó, đúng hay sai và với quyền lực đó họ có thể ra lệnh rằng bạn làm theo cách đó (hoặc bỏ, bị sa thải, hoặc bằng cách nào đó lên nắm quyền). Các quy tắc này thường dựa trên ý kiến ​​vì chúng dựa trên một số loại thực tế về khả năng đọc, hiệu suất, khả năng kiểm tra, tính di động.


Vì vậy, bạn phải tìm mức độ thoải mái có thể và sẽ thay đổi cho từng lập trình viên riêng lẻ. Tôi nghĩ mức độ tối ưu hóa phải được quyết định bởi yêu cầu hiệu năng của từng đoạn mã, chứ không phải theo từng lập trình viên thích gì.
Svick

Trình biên dịch chắc chắn, giả sử lập trình viên đã bảo trình biên dịch tối ưu hóa các trình biên dịch thường mặc định là không tối ưu hóa (tại dòng lệnh IDE có thể có một mặc định khác nếu được sử dụng). Nhưng lập trình viên có thể không biết đủ để tối ưu hóa kích thước của hàm và với càng nhiều mục tiêu thì nó sẽ trở nên vô ích? Hiệu suất điều chỉnh tay có xu hướng có tác động tiêu cực đến khả năng đọc và đặc biệt là khả năng duy trì, khả năng kiểm tra có thể đi theo bất kỳ cách nào.
old_timer

2

Phụ thuộc vào trình biên dịch của bạn thông minh như thế nào. Nói chung, cố gắng vượt qua trình tối ưu hóa là một ý tưởng tồi và thực sự có thể cướp đi trình biên dịch các cơ hội để tối ưu hóa. Đối với người mới bắt đầu, bạn có thể không có bất kỳ manh mối nào về những gì nó có thể làm và hầu hết những gì bạn làm thực sự ảnh hưởng đến việc nó cũng làm như thế nào.

Tối ưu hóa sớm là khái niệm các lập trình viên cố gắng làm điều đó và kết thúc với việc khó duy trì mã không thực sự nằm trên con đường quan trọng của những gì họ đang cố gắng làm. Cố gắng vắt kiệt CPU càng nhiều càng tốt khi hầu hết thời gian ứng dụng của bạn thực sự bị chặn chờ đợi các sự kiện IO, là điều tôi thấy rất nhiều ví dụ.

Cách tốt nhất là viết mã cho tính chính xác và sử dụng một trình lược tả để tìm ra các tắc nghẽn hiệu suất thực tế và khắc phục những lỗi đó bằng cách phân tích những gì trên đường dẫn quan trọng và liệu nó có thể được cải thiện hay không. Thường thì một vài sửa chữa đơn giản đi một chặng đường dài.


0

[yếu tố thời gian máy tính]

Việc tái cấu trúc theo hướng khớp nối lỏng lẻo và các chức năng nhỏ hơn có ảnh hưởng đến tốc độ mã không?

Vâng, nó làm. Nhưng tùy thuộc vào thông dịch viên, trình biên dịch và trình biên dịch JIT để loại bỏ mã "đường may / dây" này, và một số làm tốt hơn các trình biên dịch khác, nhưng một số thì không.

Mối quan tâm nhiều tệp thêm vào chi phí I / O, do đó cũng ảnh hưởng đến tốc độ khá nhiều (trong thời gian máy tính).

[yếu tố tốc độ của con người]

(Và tôi có nên quan tâm không?)

không bạn không nên quan tâm. Máy tính và mạch rất nhanh trong những ngày này và các yếu tố khác chiếm lĩnh, chẳng hạn như độ trễ mạng, I / O cơ sở dữ liệu và bộ nhớ đệm.

Vì vậy, làm chậm 2x - 4x trong quá trình thực thi mã gốc sẽ thường bị nhấn chìm bởi các yếu tố khác.

Theo như tải nhiều tệp, điều đó thường được quan tâm bởi các giải pháp bộ đệm khác nhau. Có thể mất nhiều thời gian hơn để tải mọi thứ lên và hợp nhất chúng lần đầu tiên, nhưng lần sau, đối với các tệp tĩnh, bộ đệm ẩn hoạt động như thể một tệp đang được tải. Bộ nhớ đệm là một giải pháp để tải nhiều tập tin.


0

TRẢ LỜI (trong trường hợp bạn bỏ lỡ)

Có, bạn nên quan tâm, nhưng quan tâm đến cách bạn viết mã chứ không phải về hiệu suất.

Nói ngắn gọn

Không quan tâm đến hiệu suất

Trong bối cảnh của câu hỏi, các trình biên dịch và thông dịch viên thông minh hơn đã quan tâm đến điều đó

Đừng quan tâm đến việc viết mã duy trì

Mã nơi chi phí bảo trì là trên mức độ hiểu biết hợp lý của con người. tức là không viết 1000 hàm nhỏ hơn làm cho mã không thể hiểu được ngay cả khi bạn hiểu từng hàm và không viết 1 hàm đối tượng thần quá lớn để hiểu, nhưng hãy viết 10 hàm được thiết kế tốt có ý nghĩa với con người và dễ bảo trì.

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.