在您经常需要执行这些检查的某些情况下,可以从Interning 获得很大的性能改进。
实习仍然需要我们有一些字符串查找数据结构,比如树或哈希表。但是,我们很少执行这些繁重的查找:具体而言,我们仅在某些原始文本输入从环境到达我们的软件系统时才执行它们。
那时,我们把输入的文本当作一个字符串,intern它:在现有的字符串集合中查找它,然后将它转换为一个原子。原子是数据的小单位,通常是单个字的数量,例如机器指针。如果字符串不存在,interning 函数会为我们提供一个新的、唯一的原子。否则,它会为我们提供与之前为该字符串提供的相同原子。
一旦我们将输入字符串嵌入到原子中,我们总是使用原子来代替它们。所以我们不是比较两个字符串是否相同,而是比较两个原子是否相同,这是一种“快得令人眼花缭乱”的单字比较操作。 (当我们需要以可读的方式打印原子时,我们仍然使用字符串:再次在我们的系统和外部世界之间的边界处)。
Interning 来自 Lisp:在 Lisp 中,符号是原子。在原始源代码中,它们是文本的,因此当代码被读入内存时,符号名称会被内部生成原子,这些原子基本上是指向符号对象的指针。
实习出现在其他地方,例如 X Window 系统(XInternAtom 函数):
Atom XInternAtom(Display *display, char *atom_name, Bool only_if_exists)
在Microsoft Windows API 中未使用术语“实习生”,但该函数返回称为ATOM 的内容:Lisp 术语。实习的不是简单的字符串,而是“类”结构:
ATOM WINAPI RegisterClass(const WNDCLASS *lpWndClass);
在这两个系统中,这些原子是系统范围的(在 X 的情况下是服务器范围的),并且可以在它们所代表的对象的位置进行相等性比较。在 Windows 中,如果您有两个相等的 ATOM 值,则它们是同一个类。
GoF 书中的Flyweight Design Pattern 本质上是对实习的再发明,扩展到字符串以外的结构(如上述 Win32 API 中的WNDCLASS);所以如果你想把这个想法“推销”给你的老板,你可以从这个角度来看待它。