| 
 |  | 
To summarize, here is a comparison of the complexity of Symbols and Strings, for the operations they both support:
| Symbol | String | |
|---|---|---|
| null constructor | 1 inline pointer assignment plus one increment | O(1) | 
| copy constructor | 1 inline pointer assignment plus one increment | O(1) | 
| construct from char* | O(length of string) + | O(length of string | 
| assignment | 1 inline pointer assignment | O(1) | 
| equality | 1 inline pointer comparison | O(length of longer string) | 
| comparison ++ | 1 inline pointer comparison | O(length of shorter string) | 
| hash | 0(hash value is cached) | O(length of string) ++ | 
       Symbol foo("foo");
       Symbol bar("bar");
       if (foo > bar)  // ??
           // ..
the comparison may or may not be true; indeed, the result may change from execution to execution. Comparison is still always a total order, however. The reason for providing this behavior is because a non-lexicographic total order operation can be implemented by a single inline pointer comparison:
       int Symbol::operator<(const Symbol& s) {
           return p < s.p;
       }
Since certain typical uses of Symbol require a total order operation, but do not require that operation to be lexicographic (for example, as the key type of Map(3C++), this behavior is desirable. If the user needs to do lexicographic comparison, the underlying strings can be compared:
       if (foo.the_string() > bar.the_string())
           // true, lexicographic comparison
           // ...
Notice, however, that the complexity of this operation is now O(length of shorter string).