Sự bi quan lố bịch nhất bạn từng thấy là gì? [đóng cửa]


145

Chúng ta đều biết rằng tối ưu hóa sớm là gốc rễ của mọi tội lỗi vì nó dẫn đến mã không thể đọc được / không thể nhầm lẫn. Tệ hơn nữa là sự bi quan, khi ai đó thực hiện "tối ưu hóa" bởi vì họ nghĩ rằng nó sẽ nhanh hơn, nhưng cuối cùng lại chậm hơn, cũng như bị lỗi, không thể nhận ra, v.v ... Ví dụ nực cười nhất về điều này mà bạn đã thấy là gì ?


21
"Bi quan" là một từ tuyệt vời.
mqp

Chỉ trong trường hợp bạn không biết, họ đã nói về chủ đề của bạn ở đây trên podcast mới nhất.
mmcdole

Câu trả lời:


81

Trong một dự án cũ, chúng tôi đã thừa hưởng một số lập trình viên hệ thống nhúng (nếu không xuất sắc), người có kinh nghiệm Z-8000 lớn.

Môi trường mới của chúng tôi là Sparc Solaris 32-bit.

Một trong những kẻ đã đi và thay đổi tất cả các int thành quần short để tăng tốc mã của chúng tôi, vì lấy 16 bit từ RAM nhanh hơn lấy 32 bit.

Tôi đã phải viết một chương trình demo để chỉ ra rằng việc lấy các giá trị 32 bit trên hệ thống 32 bit nhanh hơn lấy các giá trị 16 bit và giải thích rằng để lấy giá trị 16 bit, CPU phải tạo ra một chiều rộng 32 bit truy cập bộ nhớ và sau đó che dấu hoặc dịch chuyển các bit không cần thiết cho giá trị 16 bit.


16
Này, bạn đã học toán ở đâu? 2 hướng dẫn với 1 lần truy cập bộ nhớ cache / RAM rõ ràng nhanh hơn 1 hướng dẫn với 1 lần truy cập bộ nhớ cache / RAM!
Dao cạo bão

2
@RazorStorm Trên các máy sau này, nơi băng thông và bộ đệm là quý hơn, điều ngược lại sẽ đúng. Bitmask / shift là rẻ, nhưng bạn muốn phù hợp với bộ nhớ cache càng nhiều càng tốt và cũng giảm thiểu băng thông.
Jed

206

Tôi nghĩ rằng cụm từ "tối ưu hóa sớm là gốc rễ của mọi tội lỗi" là cách sử dụng. Đối với nhiều dự án, nó đã trở thành một cái cớ để không tính đến hiệu suất cho đến khi muộn trong một dự án.

Cụm từ này thường là một cái nạng cho mọi người để tránh làm việc. Tôi thấy cụm từ này được sử dụng khi mọi người thực sự nên nói "Gee, chúng tôi thực sự không nghĩ về điều đó ngay từ đầu và không có thời gian để giải quyết nó ngay bây giờ".

Tôi đã thấy nhiều ví dụ "lố bịch" hơn về các vấn đề hiệu suất câm so với các ví dụ về các vấn đề được đưa ra do "bi quan"

  • Đọc cùng khóa đăng ký hàng nghìn (hoặc 10 nghìn) lần trong khi khởi chạy chương trình.
  • Tải cùng một DLL hàng trăm hoặc hàng nghìn lần
  • Lãng phí byte lớn của bộ nhớ bằng cách giữ đường dẫn đầy đủ đến các tệp không cần thiết
  • Không tổ chức cấu trúc dữ liệu để chúng chiếm nhiều bộ nhớ hơn mức cần thiết
  • Định cỡ tất cả các chuỗi lưu trữ tên tệp hoặc đường dẫn đến MAX_PATH
  • Bỏ phiếu miễn phí cho điều có sự kiện, cuộc gọi lại hoặc cơ chế thông báo khác

Điều tôi nghĩ là một tuyên bố tốt hơn là: "tối ưu hóa mà không đo lường và hiểu không hoàn toàn tối ưu hóa - đó chỉ là thay đổi ngẫu nhiên".

Công việc hiệu suất tốt là tốn thời gian - thường là do sự phát triển của tính năng hoặc thành phần.


46
"Sớm" là từ khóa của trích dẫn đó. Việc bạn chia sẻ lại thành "tối ưu hóa mà không cần đo lường và hiểu" dường như không thay đổi ý nghĩa một chút nào. Đó chính xác là những gì Knuth có nghĩa.
Bill Lizard

13
@Foredecker: ngay trên. Quá nhiều người quên đi bối cảnh, trong đó đặt câu trích dẫn đó kiên quyết chống lại sự vi mô hóa. Phân tích một vấn đề để chọn thuật toán thích hợp trước khi thực hiện nó không phải là quá sớm, nhưng quá thường xuyên, trích dẫn đó được đưa lên để biện minh cho giải pháp lười biếng nhất, kém hiệu quả nhất.
Shog9

5
Nó thực sự phụ thuộc vào từng trường hợp riêng lẻ, có nhiều trường hợp tối ưu hóa sớm trở thành một vấn đề, hơn là kế hoạch tối ưu hóa không đầy đủ trở thành một vấn đề
Mark Rogers

12
-1: Có sự khác biệt giữa "tối ưu hóa" và thiết kế phù hợp. Đối với những người không thể nói, một nguyên tắc nhỏ là "tối ưu hóa" làm cho mã khó đọc hơn, nhưng nhanh hơn hoặc hiệu quả hơn. Một thiết kế tốt hơn sẽ làm cho mã dễ đọc hơn (hoặc ít nhất là không tệ hơn) hiệu quả hơn.
TED

5
Nếu nó được sử dụng quá mức, thì dân số đặt câu hỏi về SO sẽ bị đè nặng lên các ngoại lệ. : D
dkretz

114

Cơ sở dữ liệu là sân chơi bi quan.

Yêu thích bao gồm:

  • Chia bảng thành nhiều phần (theo phạm vi ngày, phạm vi chữ cái, v.v.) vì nó "quá lớn".
  • Tạo một bảng lưu trữ cho các bản ghi đã nghỉ hưu, nhưng tiếp tục UNION nó với bảng sản xuất.
  • Sao chép toàn bộ cơ sở dữ liệu theo (bộ phận / khách hàng / sản phẩm / v.v.)
  • Chống lại việc thêm các cột vào một chỉ mục vì nó làm cho nó quá lớn.
  • Tạo nhiều bảng tóm tắt vì tính toán lại từ dữ liệu thô quá chậm.
  • Tạo các cột với các trường con để tiết kiệm không gian.
  • Không chuẩn hóa thành các trường như là một mảng.

Đó là trên đỉnh đầu của tôi.


Chống lại nhu cầu lập chỉ mục chỉ là đau đớn để suy nghĩ.
Bill Lizard

2
Vâng, tôi biết ai đó làm việc cho một công ty dầu mỏ lớn của Hoa Kỳ nơi gần như tất cả các bảng của họ có bảng lưu trữ được liên kết và hầu hết các truy vấn chọn từ các chế độ xem UNION các cặp bảng. Hiệu suất là như bạn mong đợi!
Tony Andrew

Hah, tôi nghĩ rằng tất cả các DBA phải xuống liên minh với lộ trình lưu trữ bảng tại một số điểm. Nó luôn luôn có vẻ rất hợp lý vào thời điểm đó.
Cruachan

3
Tôi thêm: chia cơ sở dữ liệu trong một số cơ sở dữ liệu khác nhau (khách hàng ac, khách hàng df, v.v.)
Gabriele D'Antona

Bạn có thể giải thích về "Không chuẩn hóa thành các trường như là một mảng."? Bạn có ý nghĩa gì ở đây?
Bart van Heukelom

87

Tôi nghĩ rằng không có quy tắc tuyệt đối: một số thứ được tối ưu hóa tốt nhất, và một số thì không.

Ví dụ, tôi làm việc trong một công ty nơi chúng tôi nhận được các gói dữ liệu từ các vệ tinh. Mỗi gói có giá rất nhiều tiền, vì vậy tất cả các dữ liệu được tối ưu hóa cao (nghĩa là đóng gói). Ví dụ: vĩ độ / kinh độ không được gửi dưới dạng giá trị tuyệt đối (phao), mà là độ lệch so với góc "tây bắc" của vùng "hiện tại". Chúng tôi đã phải giải nén tất cả dữ liệu trước khi nó có thể được sử dụng. Nhưng tôi nghĩ rằng đây không phải là bi quan, đó là tối ưu hóa thông minh để giảm chi phí truyền thông.

Mặt khác, các kiến ​​trúc sư phần mềm của chúng tôi đã quyết định rằng dữ liệu được giải nén phải được định dạng thành một tài liệu XML rất dễ đọc và được lưu trữ trong cơ sở dữ liệu của chúng tôi (trái ngược với việc mỗi trường được lưu trữ trong một cột tương ứng). Ý tưởng của họ là "XML là tương lai", "không gian đĩa là rẻ" và "bộ xử lý là rẻ", do đó không cần phải tối ưu hóa bất cứ điều gì. Kết quả là các gói 16 byte của chúng tôi đã được chuyển thành các tài liệu 2kB được lưu trữ trong một cột và đối với các truy vấn đơn giản, chúng tôi phải tải megabyte tài liệu XML vào bộ nhớ! Chúng tôi đã nhận được hơn 50 gói mỗi giây, vì vậy bạn có thể tưởng tượng hiệu suất trở nên khủng khiếp như thế nào (BTW, công ty đã phá sản).

Vì vậy, một lần nữa, không có quy tắc tuyệt đối. Vâng, đôi khi tối ưu hóa quá sớm là một sai lầm. Nhưng đôi khi phương châm "cpu / không gian đĩa / bộ nhớ là rẻ" là gốc rễ thực sự của mọi tội lỗi.


37
Tôi đồng ý "cpu / dung lượng đĩa / bộ nhớ là rẻ" là gốc rễ thực sự của mọi tội lỗi. +1
ksuralta

5
Tôi cũng đã nghe nói rằng XML cũng rất tệ. Một công ty khác
n8wrl

19
@ksuralta: "Cpu / dung lượng đĩa / bộ nhớ rẻ" là một lý do thuận tiện để tránh suy nghĩ. Tránh suy nghĩ là gốc rễ tưởng tượng của mọi tội lỗi.
Piskvor rời khỏi tòa nhà vào

Việc XML hóa này cũng xảy ra tại nơi làm việc của tôi, tiếp theo là JSONization. Tất cả để tránh một số thiết kế cơ sở dữ liệu quan hệ "tốn nhiều công sức".
Tanzania87

75

Chúa ơi, tôi nghĩ rằng tôi đã thấy tất cả. Thường xuyên hơn không phải là một nỗ lực để khắc phục các vấn đề về hiệu suất bởi một người quá lười biếng để khắc phục sự cố dẫn đến NGUYÊN NHÂN của những vấn đề về hiệu suất đó hoặc thậm chí nghiên cứu xem có thực sự có vấn đề về hiệu suất hay không. Trong nhiều trường hợp này, tôi tự hỏi liệu đó không chỉ là trường hợp người đó muốn thử một công nghệ cụ thể và tuyệt vọng tìm kiếm một chiếc đinh phù hợp với cây búa mới sáng bóng của họ.

Đây là một ví dụ gần đây:

Kiến trúc sư dữ liệu đến với tôi với một đề xuất phức tạp để phân vùng theo chiều dọc một bảng chính trong một ứng dụng khá lớn và phức tạp. Anh ta muốn biết loại nỗ lực phát triển nào sẽ là cần thiết để điều chỉnh cho sự thay đổi. Cuộc trò chuyện diễn ra như sau:

Tôi: Tại sao bạn xem xét điều này? Vấn đề bạn đang cố gắng giải quyết là gì?

Ngài: Bảng X quá rộng, chúng tôi đang phân vùng nó vì lý do hiệu năng.

Tôi: Điều gì khiến bạn nghĩ nó quá rộng?

Ngài: Nhà tư vấn nói rằng có quá nhiều cột trong một bảng.

Tôi: Và điều này có ảnh hưởng đến hiệu suất?

Ngài: Có, người dùng đã báo cáo sự chậm lại không liên tục trong mô-đun XYZ của ứng dụng.

Tôi: Làm thế nào để bạn biết chiều rộng của bảng là nguồn gốc của vấn đề?

Ngài: Đó là bảng chính được sử dụng bởi mô-đun XYZ và nó giống như 200 cột. Nó phải là vấn đề.

Tôi (Giải thích): Nhưng cụ thể mô-đun XYZ sử dụng hầu hết các cột trong bảng đó và các cột mà nó sử dụng là không thể đoán trước được vì người dùng định cấu hình ứng dụng để hiển thị dữ liệu họ muốn hiển thị từ bảng đó. Có khả năng 95% thời gian chúng tôi sẽ kết hợp tất cả các bảng lại với nhau dù điều đó sẽ làm giảm hiệu suất.

Ngài: Nhà tư vấn nói nó quá rộng và chúng ta cần thay đổi nó.

Tôi: ai là người tư vấn này? Tôi không biết chúng tôi đã thuê một nhà tư vấn, họ cũng không nói chuyện với nhóm phát triển.

Ngài: Chà, chúng tôi chưa thuê họ. Đây là một phần của một đề xuất mà họ đưa ra, nhưng họ khẳng định chúng tôi cần phải kiến ​​trúc lại cơ sở dữ liệu này.

Tôi: Uh huh. Vì vậy, nhà tư vấn bán dịch vụ thiết kế lại cơ sở dữ liệu nghĩ rằng chúng tôi cần thiết kế lại cơ sở dữ liệu ....

Cuộc trò chuyện đã diễn ra như thế này. Sau đó, tôi đã xem xét lại bảng này và xác định rằng nó có thể được thu hẹp với một số chuẩn hóa đơn giản mà không cần các chiến lược phân vùng kỳ lạ. Điều này, tất nhiên hóa ra là một điểm cần thiết khi tôi điều tra các vấn đề về hiệu suất (trước đây không được báo cáo) và theo dõi chúng theo hai yếu tố:

  1. Thiếu chỉ mục trên một vài cột quan trọng.
  2. Một vài nhà phân tích dữ liệu giả mạo đã định kỳ khóa các bảng chính (bao gồm cả bảng "quá rộng") bằng cách truy vấn trực tiếp cơ sở dữ liệu sản xuất với MSAccess.

Tất nhiên, kiến ​​trúc sư vẫn đang thúc đẩy phân vùng dọc của bảng treo vào vấn đề meta "quá rộng". Anh ta thậm chí còn củng cố trường hợp của mình bằng cách nhận được đề xuất từ ​​một nhà tư vấn cơ sở dữ liệu khác, người có thể xác định chúng tôi cần thay đổi thiết kế lớn cho cơ sở dữ liệu mà không cần nhìn vào ứng dụng hoặc chạy bất kỳ phân tích hiệu suất nào.


Aaag MSAccess để prod. Chúng tôi đã viết một thủ tục để loại bỏ tất cả các kết nối truy cập cứ sau vài phút tp cuối cùng cũng nhận được thông báo rằng nó rất tệ.
Nat

1
Chúng tôi đã có một công việc tương tự, nhưng nó đã đi vào sử dụng. Công bằng mà nói, Access không phải là vấn đề, nó chỉ giúp người mới dễ dàng tạo / chạy các truy vấn không phù hợp.
JohnFx

Chúng tôi có một sự phụ thuộc tại công ty của chúng tôi vào các kết nối truy cập ad hoc kế thừa vào DB sản xuất. Không có gì giống như một vài SQL thông thường để quên một mệnh đề WHERE và bế tắc các bảng chính!
HardCode

35
"Tôi nghe nói mauve có nhiều RAM nhất"
Piskvor rời khỏi tòa nhà vào

Nó có thể trở nên tồi tệ. Trình soạn thảo truy vấn Excel khóa cơ sở dữ liệu đầy đủ khi sử dụng nó. Khi tôi không biết về nó, tôi đã để một ví dụ về nó mở cho phần tốt hơn của ngày trong khi tôi làm việc trong một cái gì đó khác. Điều tồi tệ nhất là MS SQL Server đã không báo cáo tên người dùng / máy chính xác đang thực hiện khóa. Tôi nhận ra nhiều giờ sau đó, tôi là lý do của việc khóa vì các bảng bị khóa là một phần của chế độ xem mà tôi đang truy vấn và đã kiểm tra mọi thứ khác trước.
Esteban Küber

58

Tôi đã thấy mọi người sử dụng alphadrive-7 để hoàn toàn ủ CHX-LT. Đây là một thực tế không phổ biến. Cách thực hành phổ biến hơn là khởi tạo biến áp ZT để giảm bộ đệm (do khả năng chống quá tải ròng lớn hơn) và tạo ra các biểu thức java theo kiểu.

Hoàn toàn bi quan!


10
có lẽ họ đang cố gắng tạo ra tụ điện thông lượng
Mikeage

6
Vì vậy, về cơ bản, nguyên tắc mới duy nhất liên quan là thay vì năng lượng được tạo ra bởi chuyển động tương đối của dây dẫn và từ thông, nó được tạo ra bởi sự tương tác phương thức của sự miễn cưỡng từ tính và độ bền điện dung?
Matt Rogish

17
+1 vì dù sao màn hình của tôi cũng cần được vệ sinh ;-)
RBerteig

1
Chỉ trích!! Nhưng những gì về hiệu ứng di truyền điện chéo. Tôi nghĩ rằng nó nên được đưa vào xem xét quá. Hoặc chủ đề có thể biến thành zombie.
Suraj Chandran

1
Ba từ: "Vòng bi Chrome Muffler."
Allbite

53

Tôi thừa nhận không có gì làm rung chuyển Trái đất, nhưng tôi đã bắt gặp những người sử dụng StringBuffer để nối các Chuỗi bên ngoài một vòng lặp trong Java. Nó là một cái gì đó đơn giản như biến

String msg = "Count = " + count + " of " + total + ".";

vào

StringBuffer sb = new StringBuffer("Count = ");
sb.append(count);
sb.append(" of ");
sb.append(total);
sb.append(".");
String msg = sb.toString();

Nó được sử dụng khá phổ biến để sử dụng kỹ thuật trong một vòng lặp, bởi vì nó nhanh hơn đáng kể. Vấn đề là, StringBuffer đã được đồng bộ hóa, vì vậy thực sự có thêm chi phí nếu bạn chỉ nối một vài Chuỗi. (Không đề cập đến sự khác biệt là hoàn toàn không đáng kể trên thang đo này.) Hai điểm khác về thực hành này:

  1. StringBuilder không được đồng bộ hóa, do đó, nên được ưu tiên hơn StringBuffer trong trường hợp mã của bạn không thể được gọi từ nhiều luồng.
  2. Các trình biên dịch Java hiện đại sẽ biến việc nối chuỗi có thể đọc thành mã byte được tối ưu hóa cho bạn khi nào cũng phù hợp.

3
Đầu tiên: Tại sao bạn không sử dụng ít nhất Java 5? Thứ hai: Có, bạn có thể. Làm thế nào mà bạn có thể đếm đến 5 trong ví dụ đầu tiên, nhưng không phải là thứ hai? Nó sử dụng cùng một chuỗi ký tự như đầu tiên. Viết mã có thể đọc và để trình biên dịch quyết định khi nào nên sử dụng StringBuffer đằng sau hậu trường.
Bill Lizard

4
@ MetroidFan2002: Chuỗi ký tự trong ví dụ thứ hai cũng là các đối tượng. Như tôi đã nói trong câu trả lời, sự khác biệt là không đáng kể ở quy mô này.
Bill Lizard

1
Điều đó không có nghĩa là nó thay thế mỗi Chuỗi bằng StringBuffer của riêng nó. Việc tối ưu hóa trình biên dịch thực hiện làm giảm số lượng đối tượng được tạo.
Bill the Lizard

3
@Eric: Chuỗi tin nhắn = "Đếm =" + đếm + "của" + tổng + "."; thường được biên dịch trong Java thành String dir = new StringBuffer (). append ("Count"). append (Count) .append ("of") .append (Total) .append ("."). toString (); ... đó chính xác là những gì ví dụ thứ hai làm.
Grant Wagner

3
Ông Wagner có một điều là BẠN phải xem xét tất cả các cuộc gọi phương thức này chứ không phải trình biên dịch. Bạn phải viết chúng và hiểu chúng sau này. Trình biên dịch nào cũng làm như vậy. Vì vậy, khả năng đọc là quan trọng hơn trong trường hợp này.
ypnos

47

Tôi đã từng thấy một cơ sở dữ liệu MSSQL sử dụng bảng 'Root'. Bảng gốc có bốn cột: GUID (mã định danh duy nhất), ID (int), LastModDate (datetime) và CreateDate (datetime). Tất cả các bảng trong cơ sở dữ liệu là Foreign Key'd vào bảng Root. Bất cứ khi nào một hàng mới được tạo trong bất kỳ bảng nào trong db, bạn phải sử dụng một vài thủ tục được lưu trữ để chèn một mục trong bảng Root trước khi bạn có thể đến bảng thực tế mà bạn quan tâm (thay vì cơ sở dữ liệu thực hiện công việc cho bạn với một vài kích hoạt đơn giản kích hoạt).

Điều này tạo ra một mớ hỗn độn vô dụng và đau đầu, yêu cầu bất cứ điều gì được viết trên đó để sử dụng sprocs (và loại bỏ hy vọng của tôi về việc giới thiệu LINQ cho công ty. Có thể nhưng không đáng để đau đầu), và không cần phải đau đầu ' thậm chí hoàn thành những gì nó phải làm.

Nhà phát triển đã chọn đường dẫn này bảo vệ nó theo giả định rằng điều này đã tiết kiệm hàng tấn không gian vì chúng tôi không sử dụng Hướng dẫn trên chính các bảng (nhưng ... không phải là GUID được tạo trong bảng Root cho mỗi hàng chúng tôi tạo ra?) , cải thiện hiệu suất bằng cách nào đó và làm cho "dễ dàng" kiểm toán các thay đổi đối với cơ sở dữ liệu.

Ồ, và sơ đồ cơ sở dữ liệu trông giống như một con nhện đột biến từ địa ngục.


42

Làm thế nào về POBI - bi quan rõ ràng bằng ý định?

Collegue của tôi trong những năm 90 đã mệt mỏi khi bị CEO đá vào mông chỉ vì CEO đã dành ngày đầu tiên cho mỗi bản phát hành phần mềm ERP (một tùy chỉnh) với các vấn đề về hiệu suất trong các chức năng mới. Ngay cả khi các chức năng mới đã nghiền nát hàng gigabyte và biến điều không thể thành có thể, anh ta luôn tìm thấy một số chi tiết, hoặc thậm chí là vấn đề lớn, để than vãn. Anh ta tin rằng biết nhiều về lập trình và có những cú đá của mình bằng cách đá lừa lập trình viên.

Do bản chất bất tài của những lời chỉ trích (anh ta là CEO, không phải là nhân viên IT), đồng nghiệp của tôi không bao giờ quản lý để làm cho đúng. Nếu bạn không gặp vấn đề về hiệu suất, bạn không thể loại bỏ nó ...

Cho đến khi có một bản phát hành, anh ta đã đưa rất nhiều lệnh gọi hàm Delay (200) (đó là Delphi) vào mã mới. Chỉ mất 20 phút sau khi phát trực tiếp, và anh ta được lệnh xuất hiện trong văn phòng của CEO để trực tiếp nhận những lời lăng mạ quá hạn của mình.

Chỉ có điều bất thường cho đến nay là đồng nghiệp của tôi câm lặng khi anh ta quay lại, mỉm cười, đùa giỡn, đi ra ngoài mua một hoặc hai BigMac trong khi anh ta thường đá bàn, châm chọc về CEO và công ty, và dành phần còn lại của ngày để chết. .

Đương nhiên, đồng nghiệp của tôi bây giờ nghỉ ngơi một hoặc hai ngày tại bàn làm việc của anh ấy, cải thiện kỹ năng nhắm của anh ấy trong Quake - sau đó vào ngày thứ hai hoặc thứ ba, anh ấy đã xóa các cuộc gọi Trì hoãn, xây dựng lại và phát hành một "bản vá khẩn cấp" mà anh ấy đã truyền bá rằng anh ấy đã dành 2 ngày 1 đêm để sửa các lỗ hổng hiệu suất.

Đây là lần đầu tiên (và duy nhất) mà CEO độc ác nói "công việc tuyệt vời!" cho anh ta. Đó là tất cả những gì được tính, phải không?

Đây là POBI thực sự.

Nhưng nó cũng là một loại tối ưu hóa quy trình xã hội, vì vậy nó ổn 100%.

Tôi nghĩ.


10
Tôi nhớ ai đó đã viết về một ứng dụng xử lý dữ liệu được bán ở các cấp độ khác nhau trong đó "Lite" chỉ có thể tạo ra một vài bộ dữ liệu mỗi giây, phiên bản "superduper" hàng ngàn. Sự khác biệt mã nguồn duy nhất là Ngủ (N).
peterchen

1
Xuất sắc! Tôi muốn giới thiệu tiêu chuẩn đó trong một tình huống như thế. Khi bắt đầu phát triển, hãy phân bổ một khối lớn bộ nhớ và thêm một số cuộc gọi ngủ, và bất cứ khi nào bạn cần thực hiện một số hiệu suất, chỉ cần nhai chúng xuống. Nó được gọi là một người làm phép lạ;)
RCIX

Thật không may, việc vá Sleeps thành NOP rất dễ dàng, do đó phiên bản lite có thể bị bẻ khóa rất dễ dàng. Dự trữ "tối ưu hóa" này có thể yêu cầu trình đóng gói thực thi để làm cho việc gỡ lỗi và vá lỗi khó hơn.
TheBlastOne

32

"Độc lập cơ sở dữ liệu". Điều này có nghĩa là không có procs được lưu trữ, kích hoạt, vv - thậm chí không có bất kỳ khóa ngoại nào.


8
Đây có phải là "sự độc lập" theo nghĩa là bạn ở xa cơ sở dữ liệu, bạn đã quên dữ liệu là gì? Trừu tượng hóa không cần thiết trên cơ sở dữ liệu "để tránh những cơn đau di cư" là một tiểu cảnh thú cưng; bạn sẽ không cần nó
Cướp

8
Khá nhiều. Kiến trúc sư phi hành gia tại nơi làm việc. Tôi đã xây dựng các ứng dụng web kể từ khi có một trang web và trong thời gian đó tôi chưa bao giờ thực sự chuyển từ nền tảng db này sang nền tảng db khác.
chris

5
Tôi chắc chắn điều đó xảy ra, nhưng thật hiếm khi bạn là một thằng ngốc nếu bạn thiết kế kiến ​​trúc của mình xung quanh khả năng đó.
chris

6
harpo, đó là một tình huống khác - đó là một yêu cầu trong trường hợp đó. Tôi đang nói về khi nó không phải là một yêu cầu, nhưng AA quyết định rằng nó "có thể" vào một lúc nào đó.
chris

3
@ Tất cả: Độc lập DB có thể khiến bạn phải trả giá, vâng, nhưng sản phẩm của chúng tôi được chạy trong môi trường mà nhà cung cấp DB được chọn bởi giá thầu và về cơ bản chúng tôi phải chơi cùng. Một số nhà phát triển không nhận được sự sang trọng của ngăn xếp phần mềm tích hợp theo chiều dọc và phải thực hiện bất chấp điều đó.
Chris R

31
var stringBuilder = new StringBuilder();
stringBuilder.Append(myObj.a + myObj.b + myObj.c + myObj.d);
string cat = stringBuilder.ToString();

Sử dụng tốt nhất một StringBuilder mà tôi từng thấy.


9
Nói về "không rõ ràng về khái niệm"! Ồ
Eddie

3
Mát mẻ. "Khách hàng tiềm năng của tôi nói rằng tôi phải sử dụng lớp StringBuilder nếu tôi muốn nối chuỗi. Đó là những gì tôi làm. Vậy có gì sai?" Lol ...
TheBlastOne

26

Sử dụng biểu thức chính để phân tách chuỗi khi chuỗi đơn giản.split đủ


25
NHƯNG trong Java String.Split sử dụng biểu thức chính quy!
Frank Krueger

Tôi không thấy làm thế nào một Regex có thể nhanh như phân chia chuỗi nội bộ.
Andrei Rînea

2
Nhưng việc cố tình tìm kiếm một biểu thức chính được sử dụng để phân tách chuỗi và thay thế nó bằng hàm phân tách 'đơn giản' nghe có vẻ như là một ví dụ hoàn hảo về sự bi quan. Thư viện Regex đủ nhanh.
David Crawshaw

5
@David Crawshaw: Săn lùng các cơ hội tối ưu hóa vi mô làm lãng phí thời gian của con người; nụ khi viết mã, sử dụng giải pháp đủ phức tạp nhất.
Piskvor rời khỏi tòa nhà

6
-1: Nếu bạn đã quen với regexes, việc viết nó thay vì làm quen với các trình điều khiển chuỗi nội bộ ngôn ngữ 1001 là điều rất tự nhiên.
KillianDS

26

Tôi biết rất muộn về chủ đề này, nhưng tôi đã thấy điều này gần đây:

bool isFinished = GetIsFinished();

switch (isFinished)
{
    case true:
        DoFinish();
        break;

    case false:
        DoNextStep();
        break;

    default:
        DoNextStep();
}

Vâng, chỉ trong trường hợp một boolean có một số giá trị bổ sung ...


22
Đúng, Sai một cuộc thảo luận về FileNotFound
Ikke

Hey bạn nên luôn luôn có một mặc định / trường hợp khác / vv. Điều gì xảy ra khi một người sáng giá thay đổi boolean thành enum để phản ánh trạng thái khác, sau đó người tiếp theo thêm vào enum và quên sửa đổi thủ tục? Có một mặc định khi bạn không cần chi phí không có thời gian thực hiện và rất ít thời gian phát triển. Theo dõi một lỗi logic vô tình được giới thiệu xảy ra trong thời gian chạy ... Điều đó làm tốn thời gian, tiền bạc và danh tiếng. Một khâu trong thời gian tiết kiệm chín.
Oorang

1
@Oorang ... tại sao bạn lại có nó như một công tắc? Đó là một boolean - nếu / khác là tất cả những gì cần thiết.
Damovisa

@Damovisa facepalm đúng ... rất tốt rồi :) Bỏ lỡ điều đó :)
Oorang

2
Đó là Nullable <Boolean> ... :)
George Chakhidze

25

Ví dụ tồi tệ nhất tôi có thể nghĩ là một cơ sở dữ liệu nội bộ tại công ty của tôi có chứa thông tin về tất cả nhân viên. Nó nhận được cập nhật hàng đêm từ HR và có dịch vụ web ASP.NET trên đầu trang. Nhiều ứng dụng khác sử dụng dịch vụ web để điền vào những thứ như trường tìm kiếm / thả xuống.

Điều bi quan là nhà phát triển nghĩ rằng các cuộc gọi lặp lại cho dịch vụ web sẽ quá chậm để thực hiện các truy vấn SQL lặp lại. Vậy anh ấy đã làm gì? Sự kiện bắt đầu ứng dụng đọc trong toàn bộ cơ sở dữ liệu và chuyển đổi tất cả thành các đối tượng trong bộ nhớ, được lưu trữ vô thời hạn cho đến khi nhóm ứng dụng được tái chế. Mã này rất chậm, sẽ mất 15 phút để tải trong ít hơn 2000 nhân viên. Nếu bạn vô tình tái chế nhóm ứng dụng trong ngày, có thể mất 30 phút trở lên, vì mỗi yêu cầu dịch vụ web sẽ bắt đầu tải lại đồng thời nhiều lần. Vì lý do này, những người tuyển dụng mới sẽ không xuất hiện trong cơ sở dữ liệu vào ngày đầu tiên khi tài khoản của họ được tạo và do đó sẽ không thể truy cập hầu hết các ứng dụng nội bộ trong vài ngày đầu tiên, vặn ngón tay cái.

Mức độ bi quan thứ hai là người quản lý phát triển không muốn chạm vào nó vì sợ phá vỡ các ứng dụng phụ thuộc, nhưng chúng tôi vẫn tiếp tục phát sinh các ứng dụng quan trọng trên toàn công ty do thiết kế kém của một thành phần đơn giản như vậy.


28
Quản lý tốt nhất - "Không, chúng ta đừng bỏ 80 giờ lập trình viên để sửa ứng dụng này, quá tốn kém. Hãy giữ nó, để các lỗi của nó có thể tiêu tốn hơn 200 giờ người dùng mỗi tháng, cộng thêm 10 giờ lập trình viên mỗi tháng 'bảo trì'." AAAAAAAAAUGH !!!
Piskvor rời khỏi tòa nhà vào

25

Không ai có vẻ đã đề cập đến việc sắp xếp, vì vậy tôi sẽ.

Một vài lần khác nhau, tôi đã phát hiện ra rằng ai đó đã tạo ra một bong bóng bằng tay, bởi vì tình huống "không yêu cầu" một cuộc gọi đến thuật toán quicksort "quá lạ mắt" đã tồn tại. Nhà phát triển đã được bão hòa khi bong bóng thủ công của họ hoạt động đủ tốt trên mười hàng dữ liệu mà họ đang sử dụng để thử nghiệm. Nó cũng không đi đến đâu sau khi khách hàng đã thêm một vài nghìn hàng.


2
Tôi đã làm điều đó một lần, khi tôi xác định rằng thường là n = 2. Các cải tiến sản phẩm sau này đã vô hiệu hóa tiền đề của tôi và mã được thay thế PDQ.
Đánh dấu tiền chuộc

2
Yeah, nhưng nó rất hay để ghi một cái gì đó algorythm dựa tất cả bây giờ một rồi;)
UpTheCreek

20

Tôi đã từng làm việc trên một ứng dụng chứa đầy mã như thế này:

 1 tuple *FindTuple( DataSet *set, int target ) {
 2     tuple *found = null;
 3     tuple *curr = GetFirstTupleOfSet(set);
 4     while (curr) {
 5         if (curr->id == target)
 6             found = curr;
 7         curr = GetNextTuple(curr);
 8     }
 9     return found;
10 }

Chỉ cần xóa found, quay lại nullở cuối và thay đổi dòng thứ sáu thành:

            return curr;

Nhân đôi hiệu suất ứng dụng.


1
Tôi đã làm việc một lần trong một công ty nơi các hướng dẫn mã hóa yêu cầu "chỉ một lần hoàn trả vào cuối" (để duy trì). Và thực sự một số mã nhổ ra như của bạn, bởi vì họ không nghĩ (các giải pháp rõ ràng là hầu hết các lần sử dụng goto để thoát khỏi Proc hoặc thay đổi điều kiện thoát của các vòng lặp)
flolo

12
Một dòng trở lại ở đây tạo ra hành vi đáng chú ý khác nhau. Khi bạn trả lại dòng, cuối cùng bạn sẽ nhận được trận đấu FIRST, trong đó mã bạn dán sẽ trả về kết quả khớp LAST.
SoapBox

2
@SoapBox: Bạn đúng. @Dour High Arch: Việc tăng hiệu suất không liên quan gì đến quy tắc trả về đơn, vì flolo cho biết việc điều kiện vòng lặp thành (hiện tại &&! Tìm thấy) sẽ có tác dụng tương tự. GOTO đến lối ra của Proc là khủng khiếp, và đánh bại mục đích của hướng dẫn hoàn trả duy nhất.
Akusete

2
Chúc mọi người bình luận tốt. Trong trường hợp này, đáng lẽ chỉ có một tuple với mỗi ID.
Dour High Arch

7
Đó không phải là "Bi quan", phải không? Nó chỉ đơn giản là một sự tối ưu hóa đang chờ để xảy ra.
Tim Long

20

Tôi đã từng phải cố gắng sửa đổi mã bao gồm các đá quý này trong lớp Hằng

public static String COMMA_DELIMINATOR=",";
public static String COMMA_SPACE_DELIMINATOR=", ";
public static String COLIN_DELIMINATOR=":";

Mỗi trong số này đã được sử dụng nhiều lần trong phần còn lại của ứng dụng cho các mục đích khác nhau. COMMA_DELIMINATOR xả rác mã với hơn 200 sử dụng trong 8 gói khác nhau.


Ít nhất một cái gì đó như thế là dễ dàng Tìm / Thay thế từ nguồn - vẫn vậy, tôi đồng cảm.
Erik Forbes

12
Ngoài ra - Phân định? Tôi nghĩ rằng nó được đánh vần là 'delimiter'. Deliminator nghe giống như một bộ phim tồi giữa thập niên 90 mà bằng cách nào đó có 3 phần tiếp theo ...........
Erik Forbes

53
Deliminator III: Rise of the Commas
Rob

33
Một lưu ý khác, tôi rất vui khi thấy việc phân định Colins thích hợp. Mọi lập trình viên xứng đáng với muối của anh ta đều biết rằng nếu có một thứ bạn nhất định phải tách ra một cách hợp lý, đó là Colins chết tiệt.
Cướp

2
Không dễ để thực hiện một tìm kiếm và thay thế thích hợp. Vì mỗi người được sử dụng cho các mục đích khác nhau. Bất kỳ lập trình viên tốt sẽ có ít nhất làm điều gì đó như thế này: COUNTRY_LIST_DELIM = ... CLASSIFICATION_DELIM = ... vv
KitsuneYMG

19

Số lớn mọi thời đại mà tôi gặp phải nhiều lần trong phần mềm đường phố:

Không sử dụng các tính năng của DBMS vì lý do "tính di động" vì "chúng tôi có thể muốn chuyển sang nhà cung cấp khác sau".

Đọc khẩu hình của tôi. Đối với bất kỳ công việc đường phố nào: NÓ S H KHÔNG HẠNH PHÚC!


9
Nó xảy ra. MySQL -> postgresql, vì vậy chúng tôi không mất gì cả.
Thomas

Hoặc postgres / postgis -> sqlite / spatialite ... Đó là một nỗi đau ở mông ...
Philip

nó xảy ra trong các bài kiểm tra JUnit
kachanov

17

Tôi đã có một đồng nghiệp đang cố gắng đánh lừa trình tối ưu hóa trình biên dịch C của chúng tôi và viết lại mã thường xuyên mà chỉ anh ta mới đọc được. Một trong những thủ thuật yêu thích của anh ấy là thay đổi một phương thức dễ đọc như (tạo một số mã):

int some_method(int input1, int input2) {
    int x;
    if (input1 == -1) {
        return 0;
    }
    if (input1 == input2) {
        return input1;
    }
    ... a long expression here ...
    return x;
}

vào đây:

int some_method() {
    return (input == -1) ? 0 : (input1 == input2) ? input 1 :
           ... a long expression ...
           ... a long expression ...
           ... a long expression ...
}

Đó là, dòng đầu tiên của một phương thức có thể đọc được sẽ trở thành " return" và tất cả các logic khác sẽ được thay thế bằng các biểu thức bậc ba lồng nhau sâu sắc. Khi bạn cố gắng tranh luận về việc làm thế nào là không thể hiểu được, anh ta sẽ chỉ ra một thực tế là đầu ra lắp ráp phương pháp của anh ta ngắn hơn ba hoặc bốn hướng dẫn lắp ráp. Nó không nhất thiết phải nhanh hơn nhưng nó luôn nhỏ xíu chút ngắn hơn. Đây là một hệ thống nhúng mà việc sử dụng bộ nhớ đôi khi có vấn đề, nhưng có những tối ưu hóa dễ dàng hơn nhiều có thể được thực hiện so với điều này sẽ khiến mã có thể đọc được.

Sau đó, vì lý do nào đó, anh ta quyết định rằng ptr->structElementquá khó đọc, vì vậy anh ta bắt đầu thay đổi tất cả những điều này thành (*ptr).structElementlý thuyết rằng nó cũng dễ đọc hơn và nhanh hơn.

Biến mã có thể đọc thành mã không thể đọc được để cải thiện tối đa 1% và đôi khi mã thực sự chậm hơn.


Nếu nói mô-đun đang được gọi là hàng triệu và hàng triệu lần trên mỗi vòng lặp, thì tôi sẽ chấp nhận tối ưu hóa đó miễn là ông nhận xét về cái quái đó.
Michael Dorgan

2
@Michael: Tôi sẽ không, trừ khi có các phép đo chỉ ra rằng nó nhanh hơn , không chỉ ngắn hơn .
dsimcha

Trong hầu hết các tình huống các nhà điều hành ternary là hơn dễ đọc hơn if. Sự khăng khăng về các tuyên bố trên các biểu hiện trong C là giáo điều văn hóa / tôn giáo, không phải bất kỳ loại thực hành khách quan nào. (Hướng dẫn tốt hơn: nếu ternary lồng nhau quá dài để đọc, bạn cũng không nên sử dụng if.)
Leushenko

2
Vấn đề ở đây là lấy toàn bộ một hàm và thay thế nó bằng một câu lệnh duy nhất, trả về, do đó thay thế tất cả logic của toàn bộ hàm bằng các ternary lồng nhau. Nếu bạn nhìn thấy nó, bạn sẽ hiểu. Đây không phải là một điều "tôi ghét các nhà khai thác ternary" tôn giáo. Tôi không nói về việc lấy một iftrong một chức năng và thay thế nó bằng một ternary. Điều đó tốt, và thường dễ đọc hơn. Tôi đang nói về việc thay thế toàn bộ hơn 30 phương thức dòng bằng một câu lệnh hoàn trả duy nhất và các câu lệnh tạm thời lồng nhau. Không ai nghĩ rằng mã mới dễ đọc hơn, nhưng một nhà phát triển nghĩ rằng nó nhanh hơn.
Eddie

15

Trong một trong những công việc đầu tiên của tôi với tư cách là một nhà phát triển chính thức, tôi đã tiếp quản một dự án cho một chương trình đang gặp vấn đề về quy mô. Nó sẽ hoạt động hợp lý tốt trên các tập dữ liệu nhỏ, nhưng sẽ hoàn toàn sụp đổ khi được cung cấp một lượng lớn dữ liệu.

Khi tôi đi sâu vào, tôi thấy rằng lập trình viên ban đầu đã tìm cách tăng tốc mọi thứ bằng cách song song phân tích - khởi chạy một luồng mới cho mỗi nguồn dữ liệu bổ sung. Tuy nhiên, anh ta đã mắc một sai lầm ở chỗ tất cả các luồng đều yêu cầu tài nguyên dùng chung, trong đó chúng đang bế tắc. Tất nhiên, tất cả lợi ích của đồng thời biến mất. Hơn nữa, nó đã đánh sập hầu hết các hệ thống để khởi chạy hơn 100 luồng chỉ để có tất cả trừ một trong số chúng bị khóa. Máy dev của tôi là một ngoại lệ ở chỗ nó lướt qua bộ dữ liệu 150 nguồn trong khoảng 6 giờ.

Vì vậy, để khắc phục nó, tôi đã loại bỏ các thành phần đa luồng và dọn sạch I / O. Không có thay đổi nào khác, thời gian thực hiện trên bộ dữ liệu 150 nguồn giảm xuống dưới 10 phút trên máy của tôi và từ vô cực đến dưới nửa giờ trên máy công ty trung bình.


Tôi chỉ ngăn chặn điều này xảy ra trong một dự án ngày hôm nay. Bây giờ tôi biết tôi đã lựa chọn tốt.
deadalnix

14

Tôi cho rằng tôi có thể cung cấp đá quý này:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    // Find out how many bytes our value uses
    // so we don't do any uneeded work.
    if (value & 0xffff0000)
    {
        if ((value & 0xff000000) == 0)
            tmp = 3;
        else
            tmp = 4;
    }
    else if (value & 0x0000ff00)
        tmp = 2;

    switch (tmp)
    {
        case 4:
            ISQRT_INNER(15);
            ISQRT_INNER(14);
            ISQRT_INNER(13);
            ISQRT_INNER(12);
        case 3:
            ISQRT_INNER(11);
            ISQRT_INNER(10);
            ISQRT_INNER( 9);
            ISQRT_INNER( 8);
        case 2:
            ISQRT_INNER( 7);
            ISQRT_INNER( 6);
            ISQRT_INNER( 5);
            ISQRT_INNER( 4);
        case 1:
            ISQRT_INNER( 3);
            ISQRT_INNER( 2);
            ISQRT_INNER( 1);
            ISQRT_INNER( 0);
    }
#undef ISQRT_INNER
    return root;
}

Vì căn bậc hai đã được tính toán ở một nơi rất nhạy cảm, tôi có nhiệm vụ tìm kiếm một cách để làm cho nó nhanh hơn. Việc tái cấu trúc nhỏ này đã giảm thời gian thực hiện xuống một phần ba (đối với sự kết hợp giữa phần cứng và trình biên dịch được sử dụng, YMMV):

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    ISQRT_INNER (15);
    ISQRT_INNER (14);
    ISQRT_INNER (13);
    ISQRT_INNER (12);
    ISQRT_INNER (11);
    ISQRT_INNER (10);
    ISQRT_INNER ( 9);
    ISQRT_INNER ( 8);
    ISQRT_INNER ( 7);
    ISQRT_INNER ( 6);
    ISQRT_INNER ( 5);
    ISQRT_INNER ( 4);
    ISQRT_INNER ( 3);
    ISQRT_INNER ( 2);
    ISQRT_INNER ( 1);
    ISQRT_INNER ( 0);

#undef ISQRT_INNER
    return root;
}

Tất nhiên có cả hai cách nhanh hơn và tốt hơn để làm điều này, nhưng tôi nghĩ đó là một ví dụ khá gọn gàng về sự bi quan.

Chỉnh sửa: Hãy nghĩ về nó, vòng lặp không được kiểm soát thực sự cũng là một bi quan gọn gàng. Đào qua điều khiển phiên bản, tôi cũng có thể trình bày giai đoạn tái cấu trúc thứ hai, hoạt động thậm chí còn tốt hơn so với ở trên:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1 << 30, root = 0;

    while (tmp != 0)
    {
        if (value >= root + tmp) {
            value -= root + tmp;
            root += tmp << 1;
        }
        root >>= 1;
        tmp >>= 2;
    }

    return root;
}

Đây chính xác là cùng một thuật toán, mặc dù cách triển khai hơi khác, vì vậy tôi cho rằng nó đủ điều kiện.


Tôi cho rằng isqrt()tính toán floor(sqrt()), nhưng, tại sao mã này hoạt động?
Pablo H

11

Điều này có thể ở cấp độ cao hơn những gì bạn đã theo đuổi, nhưng sửa nó (nếu bạn được phép) cũng liên quan đến mức độ đau đớn cao hơn:

Nhấn mạnh vào việc cuộn một Trình quản lý quan hệ đối tượng / Lớp truy cập dữ liệu thay vì sử dụng một trong các thư viện trưởng thành, đã được kiểm tra, đã được thiết lập ngoài đó (ngay cả sau khi chúng được chỉ ra cho bạn).


Nó không phải luôn luôn là một ý tưởng tồi để cuộn mã của riêng bạn. Giống như một người khôn ngoan đã từng nói, tìm ra sự phụ thuộc và loại bỏ chúng. Nếu đó là một chức năng kinh doanh cốt lõi, hãy tự làm.
Kibbee

Tôi không bao giờ suy luận nó luôn luôn là một ý tưởng tồi. Trừ khi bạn nói Frans Bouma hoặc tương tự, tôi nghi ngờ công cụ ORM / DAL là một chức năng kinh doanh cốt lõi. Việc viết tương đương của bạn là không hiệu quả, một trường hợp phát minh lại bánh xe (vuông), thường là do hội chứng NIH.
Gordon Hartley

@Kibbee - Tôi đồng ý. Nó tốt hơn để cuộn của riêng bạn và hiểu nó hơn là sử dụng phụ thuộc của bên thứ 3. Khi nó bị hỏng (và nó sẽ) ít nhất bạn sẽ sửa nó sau đó. Tôi đã tìm thấy các lỗi trong Hibernate và Apache Commons trong quá khứ đã giết chết hoàn toàn hiệu suất của ứng dụng của chúng tôi.
CodingWithSpike

4
Một tay quay thực sự là lựa chọn duy nhất của bạn nếu không ai trong số những người thành lập có một tính năng quan trọng bạn cần.
staticsan

3
Trên thực tế, với một số ý kiến ​​ở trên, một số quan điểm khác: một sự bi quan khác là thử và lấy ORM để làm tất cả mọi thứ. Nó thường hữu ích cho 95% + trường hợp. Đối với 5% cuối cùng đó, việc bỏ qua mã thủ tục lưu trữ thủ công / các cuộc gọi thủ tục được lưu trữ trực tiếp dễ dàng hơn nhiều, v.v. để thực hiện, đơn giản hoặc cả hai.
Gordon Hartley

10

Tất cả các ràng buộc khóa ngoài đã bị xóa khỏi cơ sở dữ liệu, vì nếu không sẽ có rất nhiều lỗi.


8

Điều này không chính xác phù hợp với câu hỏi, nhưng dù sao tôi cũng sẽ đề cập đến nó một câu chuyện cảnh báo. Tôi đang làm việc trên một ứng dụng phân tán đang chạy chậm và bay xuống DC để tham gia một cuộc họp chủ yếu nhằm giải quyết vấn đề. Trưởng dự án bắt đầu phác thảo một kiến ​​trúc lại nhằm giải quyết sự chậm trễ. Tôi tình nguyện rằng tôi đã thực hiện một số phép đo vào cuối tuần qua, cô lập nút cổ chai thành một phương pháp duy nhất. Hóa ra có một bản ghi bị thiếu trong một tra cứu cục bộ, khiến ứng dụng phải đến một máy chủ từ xa trên mỗi giao dịch. Bằng cách thêm bản ghi trở lại cửa hàng địa phương, độ trễ đã được loại bỏ - vấn đề đã được giải quyết. Lưu ý kiến ​​trúc lại sẽ không khắc phục vấn đề.


8

Kiểm tra trước MỌI thao tác javascript xem đối tượng bạn đang hoạt động có tồn tại không.

if (myObj) { //or its evil cousin, if (myObj != null) {
    label.text = myObj.value; 
    // we know label exists because it has already been 
    // checked in a big if block somewhere at the top
}

Vấn đề của tôi với loại mã này dường như không ai quan tâm nếu nó không tồn tại? Chỉ cần làm gì? Đừng đưa ra phản hồi cho người dùng?

Tôi đồng ý rằng các Object expectedlỗi gây phiền nhiễu, nhưng đây không phải là giải pháp tốt nhất cho điều đó.


Giải pháp tốt nhất sau đó là gì? Tôi nghĩ thật cẩu thả khi viết mã, trong đó thỉnh thoảng xảy ra lỗi, ngay cả khi chúng không có hậu quả trực tiếp. Tất nhiên bạn không nên làm điều đó, nếu bạn không mong muốn đối tượng là null trong mọi trường hợp - có thể đây là ý của bạn.
simon

7

Làm thế nào về chủ nghĩa cực đoan YAGNI. Đó là một hình thức bi quan sớm. Có vẻ như bất cứ khi nào bạn áp dụng YAGNI, sau đó bạn sẽ cần nó, dẫn đến nỗ lực để thêm nó gấp 10 lần so với khi bạn đã thêm nó vào lúc đầu. Nếu bạn tạo ra một chương trình thành công thì tỷ lệ cược là BẠN ĐANG CẦN NÓ. Nếu bạn đã quen với việc tạo ra các chương trình có cuộc sống nhanh chóng thì hãy tiếp tục thực hành YAGNI vì sau đó tôi cho rằng YAGNI.


3
Cảm ơn bạn, tôi phát ngán với những từ viết tắt 'lập trình cực đoan' này và cách mọi người sử dụng chúng để hỗ trợ các hoạt động lười biếng, phản tác dụng.
JAL

Các nghiên cứu về các dự án thực tế cho thấy rằng yếu tố thực tế giữa trung bình mã một lần và tái sử dụng trung bình vào khoảng 3. Vì vậy, 10 chỉ là giá trị "cảm thấy", nhưng bạn có ý định đúng.
peterchen

@peterchen - bạn có nói rằng các nghiên cứu cho thấy việc viết mã có thể tái sử dụng mất ba lần thời gian dài hơn hoặc họ cho thấy mất ba lần thời gian để chuyển đổi mã một lần thành mã có thể sử dụng lại so với việc viết mã mã tái sử dụng ở nơi đầu tiên?
Jeff Sternal

@jeff: IIRC họ đã so sánh một số biện pháp phức tạp (bất cứ điều gì bạn nghĩ về chúng) của các đoạn nội tuyến mà người sói đã chuyển sang các phương pháp riêng biệt. Độ phức tạp tăng do các trường hợp bổ sung được hỗ trợ, kiểm tra tham số, v.v. (điều này khiến tôi cho rằng các phương thức khá nhỏ). Hãy để tôi thử khai thác một tài liệu tham khảo.
peterchen

6

Không chính xác tối ưu hóa sớm - nhưng chắc chắn là sai lầm - điều này đã được đọc trên trang web BBC, từ một bài viết thảo luận về Windows 7.

Ông Curran nói rằng nhóm Microsoft Windows đã nghiên cứu mọi khía cạnh của hệ điều hành để cải thiện. "Chúng tôi đã có thể tắt 400 mili giây trong thời gian tắt máy bằng cách cắt nhẹ nhạc tắt máy WAV.

Bây giờ, tôi chưa dùng thử Windows 7, vì vậy tôi có thể sai, nhưng tôi sẵn sàng đặt cược rằng có những vấn đề khác quan trọng hơn là mất bao lâu để tắt máy. Rốt cuộc, một khi tôi thấy thông báo 'Tắt Windows', màn hình sẽ tắt và tôi đang bỏ đi - 400 mili giây đó có lợi cho tôi như thế nào?


Bạn có thể sẽ thấy rằng các vấn đề khác không dễ giải thích cho những người không lập trình trên trang web BBC.
Tom Leys

Bây giờ đó là một góc mà tôi đã không cân nhắc - có lẽ tôi đang bắt đầu đánh mất sự hoài nghi của mình :-)
belugabob

400 ms là 400 ms rút điện. Có lẽ không đáng kể, nhưng có lẽ nó cộng lại theo thời gian. Tuy nhiên, không có gì tôi sẽ lo lắng.
ZachS

1
Tôi đã mất rất nhiều giờ để chờ máy ảo XP tắt để tôi có thể chuyển sang điều tiếp theo. Tôi rất biết ơn vì tắt máy nhanh hơn.
James

1
Điều thú vị là các tệp WAV được phát không đồng đều, miễn là thời gian tắt máy ngắn hơn thời gian cần thiết để tắt máy, cắt bớt tệp WAV không làm gì cả. Và thú vị hơn nữa, nếu họ tối ưu hóa việc tắt máy rất nhiều, làm thế nào mà mọi hộp Windows tôi tắt đều cần các aeon cho đến khi nó thực sự ngừng hoạt động? (Tất nhiên ngoại trừ việc sử dụng nút lớn màu đỏ.)
TheBlastOne

6

Ai đó trong bộ phận của tôi đã từng viết một lớp chuỗi. Một giao diện như thế CString, nhưng không có sự phụ thuộc của Windows.

Một "tối ưu hóa" họ đã làm là không phân bổ thêm bộ nhớ nào cần thiết. Rõ ràng không nhận ra rằng các lớp lý do như std::stringphân bổ bộ nhớ dư thừa là để một chuỗi các +=hoạt động có thể chạy trong thời gian O (n).

Thay vào đó, mỗi +=cuộc gọi đều buộc phải phân bổ lại, điều này đã biến các phần phụ lặp đi lặp lại thành thuật toán O (n²) của họa sĩ .


5

Một đồng nghiệp cũ của tôi ( thực tế là một soab ) đã được chỉ định để xây dựng một mô-đun mới cho Java ERP của chúng tôi cần thu thập và phân tích dữ liệu của khách hàng (ngành bán lẻ). Anh quyết định chia MỌI trường Lịch / Ngày trong các thành phần của nó (giây, phút, giờ, ngày, tháng, năm, ngày trong tuần, bimester, tam cá nguyệt (!)) Bởi vì "tôi sẽ truy vấn 'mọi thứ hai' như thế nào?"


3
Đó không phải là một sự tối ưu hóa sớm, anh ấy nghĩ rằng anh ấy cần phải làm điều đó cho chính xác
Pyrolistic

Chắc chắn, anh ta nghĩ rằng anh ta cần điều đó, nhưng vì hầu hết các DBMS đều có chức năng DAYOFWEEK (dấu thời gian), nên việc thực hiện lộn xộn đó là quá sớm theo quan điểm của tôi :)
Joril

1
Tôi sẽ không sử dụng nó cho OLTP, nhưng nếu bạn đang "phân tích dữ liệu của khách hàng" thì đó thực sự là một cách rất linh hoạt để thiết kế kho dữ liệu (miễn là ngày và giờ được chia thành các chiều khác nhau). Bạn có thực sự muốn gọi DAYOFWEEK () đối với hàng triệu hàng dữ liệu hay chỉ thực hiện một chỉ mục tìm kiếm đối với trường số nguyên?
Tim Medora

Chà tôi không biết có quá nhiều hàng không, nhưng chắc chắn đó không phải là lời giải thích được đưa ra :)
Joril

3

Không xúc phạm bất cứ ai, nhưng tôi vừa chấm điểm một bài tập (java) có cái này

import java.lang.*;

1
Trừ khi đây là lớp học cấp trên, tôi nghĩ bạn cần cắt giảm học sinh này một chút, trừ khi bạn dạy cô ấy đủ để biết tại sao đây không phải là một ý tưởng tốt.
Bryan Oakley

24
Tôi sẽ là người duy nhất ghi nhận sự mỉa mai của một giáo viên gọi WTF theo mã của một học sinh mà anh ấy / cô ấy có trách nhiệm giảng dạy để lập trình chính xác?
JohnFx

3
Vâng, tôi không thể thấy rằng điều này sẽ làm tổn thương. Tệ nhất là nó tuyệt vời. Sinh viên có xu hướng sử dụng sự nhất quán cứng nhắc trong khi họ đang học và nhập java.lang hoàn toàn phù hợp với những gì sinh viên đã học về nhập khẩu.
cygil

1
Cảm ơn tất cả các bạn đã cho tôi biết rõ ràng. Đó là một bài tập Sinh học tính toán và tôi đã không đếm nó, thậm chí không đề cập đến nó.
Tràn

2
@ John John: Học sinh và giáo viên không phải lúc nào cũng là cùng một người.
Eddie
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.