is
thẩm tra đối tượng danh tính, và bất kỳ việc thực hiện Python, khi nó đáp ứng đen của loại không thay đổi, là hoàn toàn miễn phí để hoặc làm cho một đối tượng mới của loại bất biến, hoặc tìm kiếm thông qua các đối tượng hiện có của loại hình đó để xem nếu một số trong số chúng có thể được tái sử dụng (bằng cách thêm một tham chiếu mới vào cùng một đối tượng cơ bản). Đây là một lựa chọn tối ưu thực dụng và không phải là tùy thuộc vào ràng buộc ngữ nghĩa, vì vậy mã của bạn sẽ không bao giờ dựa vào đường dẫn nào mà việc thực hiện cung cấp có thể thực hiện (hoặc nó có thể phá vỡ với bản phát hành lỗi/tối ưu hóa của Python!).
Hãy xem xét ví dụ:
>>> import dis
>>> def f():
... x = 'google.com'
... return x is 'google.com'
...
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('google.com')
3 STORE_FAST 0 (x)
3 6 LOAD_FAST 0 (x)
9 LOAD_CONST 1 ('google.com')
12 COMPARE_OP 8 (is)
15 RETURN_VALUE
như vậy trong thực hiện đặc biệt này, trong vòng một hàm, quan sát của bạn không áp dụng và chỉ có một đối tượng được thực hiện cho các chữ (bất kỳ nghĩa đen), và thực tế:
>>> f()
True
Thực tế là vì trong một hàm thực hiện qua bảng hằng số hằng số (để tiết kiệm bộ nhớ bằng cách không tạo nhiều đối tượng bất biến không đổi) giá rẻ và nhanh chóng, và có thể cung cấp hiệu suất tốt trở lại kể từ khi chức năng có thể được gọi là nhiều lần sau đó.
Nhưng, việc thực hiện rất giống nhau, tại dấu nhắc tương tác (Sửa: Tôi ban đầu nghĩ điều này cũng sẽ xảy ra ở cấp cao nhất của một mô-đun, nhưng một lời nhận xét của @Thomas thiết tôi ngay, xem phần sau):
>>> x = 'google.com'
>>> y = 'google.com'
>>> id(x), id(y)
(4213000, 4290864)
KHÔNG bận tâm đến việc cố gắng lưu bộ nhớ theo cách đó - id
s khác nhau, nghĩa là các đối tượng riêng biệt. Có khả năng chi phí cao hơn và lợi nhuận thấp hơn và do đó các chẩn đoán của trình tối ưu hóa thực hiện này cho biết nó không làm phiền tìm kiếm và chỉ cần đi trước. ví dụ như ở cấp cao nhất mô-đun, mỗi quan sát @Thomas', đưa ra::
Sửa
$ cat aaa.py
x = 'google.com'
y = 'google.com'
print id(x), id(y)
một lần nữa chúng ta thấy bảng-of-hằng số dựa trên bộ nhớ tối ưu hóa trong việc thực hiện này:
>>> import aaa
4291104 4291104
(kết thúc chỉnh sửa theo quan sát @Thomas).
Cuối cùng, một lần nữa về việc thực hiện giống nhau:
>>> x = 'google'
>>> y = 'google'
>>> id(x), id(y)
(2484672, 2484672)
các chẩn đoán khác nhau ở đây vì chuỗi chữ "trông giống như nó có thể là một định danh" - vì vậy nó có thể được sử dụng trong hoạt động đòi hỏi phải thực tập .. Vì vậy, trình tối ưu hóa thực hiện nó anyway (và một lần tập trung, tìm kiếm nó trở nên rất nhanh tất nhiên). Và quả thực, sự ngạc nhiên bất ngờ ...:
>>> z = intern(x)
>>> id(z)
2484672
... x
có được intern
ed lần đầu tiên (như bạn thấy, giá trị trả về của intern
là cùng một đối tượng như x
và y
, vì nó có cùng số id()
). Tất nhiên, bạn cũng không nên dựa vào điều này - trình tối ưu hóa không có tự động thực hiện bất cứ điều gì, nó chỉ là một cách tối ưu hóa heuristic; nếu bạn cần intern
chuỗi ed, intern
chúng một cách rõ ràng, chỉ để được an toàn. Khi bạn làm chuỗi thực tập một cách rõ ràng ...:
>>> x = intern('google.com')
>>> y = intern('google.com')
>>> id(x), id(y)
(4213000, 4213000)
... sau đó bạn làm đảm bảo chính xác cùng một đối tượng (ví dụ, cùng id()
) kết quả mỗi lần - vì vậy bạn có thể áp dụng vi -optimizations như kiểm tra với is
chứ không phải là ==
(Tôi đã hầu như không bao giờ tìm thấy đạt được hiệu suất tối thiểu để có giá trị phiền ;-).
Sửa: chỉ cần làm rõ, đây là những loại khác biệt hiệu suất Tôi đang nói về, trên một chậm Macbook Air ...:
$ python -mtimeit -s"a='google';b='google'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.107 usec per loop
$ python -mtimeit -s"a='goo.gle';b='goo.gle'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.106 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a is b'
10000000 loops, best of 3: 0.0966 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a == b'
10000000 loops, best of 3: 0.126 usec per loop
... vài chục nano giây hoặc cách, nhiều nhất. Vì vậy, giá trị thậm chí suy nghĩ về chỉ trong khắc nghiệt nhất "tối ưu hóa [expletive xóa] ra khỏi này [expletive xóa] hiệu suất nút cổ chai" tình huống! -)
Rất thích. Đó là một điều kỳ lạ. –
Cả hai đều là 'False' trong Python 2.5.2. –
Trong ActivePython 2.5.4.4, xem kết quả tương tự như OP. Gần như chắc chắn có một cái gì đó để làm với chuỗi interning, phải không? –