PHẢN PHÁC QUY CHÂN LÀ GÌ

     
Series làm phản Phác Quy Chân – tại sao cộng string lại chậm

Lý giải chút về thương hiệu series

返璞归真 – bội phản phác quy chân: tức thị điểm tối đa cũng đó là điểm xuất phát, được ứng dụng trong không ít lĩnh vực. Trong võ học, nó có nghĩa là đạt cho tới cảnh giới "Tối thượng" vào truyền thuyết, quên đi tất cả võ học tập trong thiên hạ, phiên bản thân đã không còn chiêu thức cầm thể, chỉ phụ thuộc ý cảnh mà dễ dàng và đơn giản xử lý.

Bạn đang xem: Phản phác quy chân là gì

Bạn đang xem: phản bội phác quy chân là gì

Võ học được ra đời từ các phương pháp cơ bản, xuất xắc thế võ công cũng tự các phương pháp cơ bản mà ra. Code học tập cũng sản xuất thành trường đoản cú bit/byte cơ bản, chương trình phức hợp đến mấy cũng dịch được ra bytecode. Đôi khi, ta đã quá quen với câu hỏi dùng thư viện, sử dụng framework cơ mà quên thì các thứ ở sâu bên dưới, không cố kỉnh được bản chất. Có những sự việc mà buộc phải nắm rõ bản chất của nó ta mới có thể giải quyết được.

Như cái thương hiệu "Phản phác hoạ Quy Chân", series này không giới thiệu công nghệ hay ngôn ngữ mới, nhưng mà sẽ tập trung quay lại phần đa cái bạn dạng chất, 1-1 giản, tinh túy nhất nhưng ít tín đồ quan tâm chú ý (Bên giờ Anh bao gồm một từ tương tự như : Back to Basic, bỏ qua những cái phức tạp, quay lại các chiếc cơ bản để gọi tận gốc vấn đề).

Ở bài viết đầu, mình vẫn nhắc sơ lại về string, cũng tương tự giải thích nguyên nhân vì sao việc cộng string sẽ ảnh hưởng tới bộ lưu trữ và performance của hệ thống (Hình minh họa và bài viết méo liên quan với nhau đâu, vì tác giả thích ráng :v).

Chuyện về String

Ngày xửa ngày xưa, thời còn học tập Java, ta thường xuyên được nghe dạy rằng khi cùng chuỗi, cần dùng StringBuilder và append, thay bởi vì cộng String. Tại sao là do String là kiểu immutable, giá chỉ trị của chính nó không thế đổi, khi cùng string ta tạo ra một string bắt đầu trong bộ nhớ. Còn StringBuilder là hình dạng mutable, cho nên vì vậy khi ta dùng append, quý hiếm của nó chuyển đổi chứ không tạo nên string mới. Cho nên vì thế dùng StringBuilder đang tiết kiệm bộ nhớ lưu trữ và chạy cấp tốc hơn.

Không tin à, hãy xem 2 đoạn code dưới đây, đoạn code dùng StringBuilder chỉ mất 4ms để chạy, còn đoạn code áp dụng String mất cho tới 4828ms (Nguồn).

Xem thêm: Lễ Cúng Giao Thừa Gồm Những Gì? Mâm Cúng Giao Thừa Gồm Những Gì

Cộng string thì có vấn đề gì

Để phân tích và lý giải vấn đề này, ta hãy thử trải nghiệm cảm xúc "Phản phác qui chân": Bỏ sang một bên những technology mới mẻ hoành tráng, những framework đồ sộ, những ngôn ngữ ảo diệu, quay lại từ mẫu thời ngày xửa rất lâu rồi còn dùng DevC, còn giúp việc với byte và bộ nhớ. Đúng vậy, những kỹ năng và kiến thức về byte, về bộ nhớ là căn cơ cho khối hệ thống kiến thức của bạn.

Hãy ghi nhớ lại cách C lưu trữ string: String là một trong những mảng những byte, gồm kí tự ở đầu cuối là kí tự null. Với cách tàng trữ này, để biết được độ nhiều năm của string, ta yêu cầu chạy một vòng lặp ban đầu từ nhỏ trỏ đựng byte đầu tiên tính đến khi gặp kí từ bỏ null. Dưới đấy là một phiên bản của hàm strcat, hàm cộng chuỗi vào C.

void strcat( char* dest, char* src ) while (*dest) dest++; while (*dest++ = *src++);Đọc code cùng suy ngẫm nhé. Loại đầu tiên, code sẽ chạy từ bỏ đầu tính đến khi chạm mặt phải null character cuối string dest, sau đó nó đã copy từng byte của string src và string dest. Nhị vòng lặp, độ phức tạp chỉ là O(n), đâu có gì gớm ghê nhỉ?? tuy nhiên, lúc ta thực hiện việc cộng chuỗi những lần, với chuỗi lâu năm thì sao?

char bigString; bigString = "";strcat(bigString,"John, ");strcat(bigString,"Paul, ");strcat(bigString,"George, ");strcat(bigString,"Joel ");Mỗi lần call strcat, vòng lặp đang chạy từ đầu tính đến cuối chuỗi, chuỗi càng lâu năm thì vòng lặp chạy càng lâu. Tới khi chuỗi string vô cùng bự thì vấn đề cộng chuỗi diễn ra rất nặng vật nài và chậm chạp chạp. Bác bỏ Joel có một câu chuyện cười (mình đọc chả thấy vui) nhằm mô tả vấn đề này.

Một cô tóc vàng bắt đầu vào nghề sơn vun phân tuyến trên tuyến đường cao tốc. Ngày đầu, cô sơn được 10 dặm, ngày ngày tiếp theo cô chỉ sơn được 7 dặm. Ông chủ nghĩ rằng cô mệt, nên cho ngủ một ngày. Sau hôm đó, cô ta có tác dụng cũng chỉ được 5 dặm. Cứ thế hằng ngày cô lại làm ít hơn. Ông chủ call cô cho tới hỏi:

– có chuyện gì xẩy ra thế? lý do năng suất của cô sút từng ngày?

– Tôi tưởng là ông phải biết chứ! Đơn giản là càng ngày, tôi càng ra đi cái thùng sơn hơn.

Tương tự như trong truyện, string gốc càng nhiều năm thì vòng lặp cần chạy càng lâu. Vì chưng đó, để giải quyết vấn đề này, một trong những phiên phiên bản khác của hàm strcat vẫn được chế tạo ra ra:

char* mystrcat( char* dest, char* src ) while (*dest) dest++; while (*dest++ = *src++); return --dest;char bigString; char *p = bigString;bigString = "";p = mystrcat(p,"John, ");p = mystrcat(p,"Paul, ");p = mystrcat(p,"George, ");p = mystrcat(p,"Joel ");Với biện pháp viết này, sau khi cộng chuỗi, ta trả ra vị trí con trỏ cuối cùng. Các lần cộng thêm, vòng lặp chỉ việc chạy từ bé trỏ được trả cho tới cuối chuỗi src thôi, không thể lặp những như thuật toán lúc đầu nữa.

Xem thêm: Tiến Vũ Vì Yêu Mà Đến : Trai Đẹp Tiến Vũ Cực Đáng Yêu Vì, Vì Yêu Mà Đến: Trai Đẹp Tiến Vũ Cực Đáng Yêu Vì


*

Kết luận

Bài viết xem thêm nhiều tự blog Joel on Software của chưng Joel, một người vừa cứng technical vừa tốt điều hành và quản lý: http://www.joelonsoftware.com/articles/fog0000000319.html. Nội dung bài viết gốc phẫu thuật xẻ không ít vấn đề về performance, bộ lưu trữ liên quan tới string, tuy vậy mình thấy không bổ ích mấy yêu cầu không chuyển vào nội dung bài viết nhé.