Khi bắt đầu sử dụng Python, nhiều người thường quen dùng toán tử + để nối chuỗi, như cách mà nhiều ngôn ngữ lập trình khác đã thực hiện, như Java chẳng hạn.
Tuy nhiên, bạn sẽ nhận ra rằng nhiều lập trình viên chuyên nghiệp lại ưa thích sử dụng join() thay vì toán tử + để nối chuỗi trong Python. Trong bài viết này, chúng ta sẽ khám phá sự khác biệt giữa hai phương pháp và tại sao bạn nên tránh sử dụng toán tử +.
Sự khác nhau giữa toán tử + và join()
Thường khi mới học Python, bạn có thể viết như sau để nối hai chuỗi:
str1 = 'I love ' str2 = 'Python.' print(str1 + str2)
Kết quả: I love Python.
Tuy nhiên, khi bạn đã làm quen với Python hơn, bạn sẽ nhận ra rằng nhiều người thường sử dụng join() để nối chuỗi như sau:
str1 = 'I love ' str2 = 'Python.' print(''.join([str1, str2]))
Kết quả: I love Python.
Bây giờ, chúng ta có thể gặp trường hợp cần nối nhiều chuỗi cùng một lúc trong một danh sách:
strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']
Ban đầu, chúng ta có thể làm như sau:
strs = ['Life', 'is', 'short,', 'I', 'use', 'Python'] def join_strings(strings): result = '' for s in strings: result += ' ' + s return result[1:] join_strings(strs)
Kết quả: Life is short, I use Python
Tuy nhiên, sau khi tìm hiểu thêm, tôi nhận ra rằng join() có thể giải quyết công việc này một cách nhanh chóng:
def join_strings_better(strings): return ' '.join(strings) join_strings_better(strs)
Điều này thực sự rất tiện lợi, như một dòng code "one line does everything" trong Python. Tuy nhiên, join() không chỉ gọn hơn cú pháp mà còn có hiệu năng tốt hơn.
So sánh hiệu năng
Chúng ta hãy so sánh hiệu năng giữa hai phương pháp. Chúng ta có thể sử dụng %timeit trong Jupyter Notebook để so sánh:
Kết quả của thử nghiệm trên 100,000 lần cho thấy join() có thể nhanh hơn gấp 4 lần so với sử dụng toán tử +.
Cách thức hoạt động của toán tử + là:
- Đối với mỗi vòng lặp, chuỗi được tìm thấy từ danh sách.
- Trình thông dịch Python thực hiện phép cộng chuỗi và khoảng trắng '', gán kết quả vào địa chỉ bộ nhớ cho chuỗi khoảng trắng.
- Sau đó, trình thông dịch nhận ra rằng cần nối chuỗi với một chuỗi khác, do đó nó sẽ áp dụng cho địa chỉ bộ nhớ của chuỗi s, đây là lần lặp đầu tiên.
- Đối với mỗi vòng lặp, trình thông dịch cần áp dụng hai lần vào địa chỉ bộ nhớ, một lần cho khoảng trắng và một lần cho chuỗi.
- Tổng cộng có 12 lần cấp phát bộ nhớ.
Còn cách thức hoạt động của join() là:
- Trình thông dịch đếm tổng số chuỗi trong danh sách (tổng cộng có 6 chuỗi).
- Điều đó có nghĩa là chuỗi được sử dụng để nối các chuỗi trong danh sách sẽ cần được lặp lại 6 - 1 = 5 lần.
- Trình thông dịch biết rằng cần tổng cộng 11 không gian bộ nhớ, vì vậy tất cả đều được cấp phát trước.
- Các chuỗi được sắp xếp theo thứ tự và kết quả được trả về.
Sự khác biệt quan trọng về việc phân bổ bộ nhớ giữa hai phương pháp là nguyên nhân chính dẫn đến sự khác biệt về hiệu năng.
Python là một ngôn ngữ kỳ diệu, với khả năng "one line can do everything". Hãy tận dụng sức mạnh của Python để đạt hiệu năng tối đa cho phần mềm chúng ta phát triển. Happy coding!!!
(Note: Các hình ảnh được lấy từ bài viết gốc)