2009-05-13 9 views
13

Si j'ai une chaîne immuable, l'algorithme de hachage est-il lancé à chaque fois que j'appelle un hachage, ou se souvient-il de la valeur (étant donné que la chaîne ne peut pas changer)?Est-ce que [Hash NSString] est calculé à chaque fois?

+1

Eh bien, pour répondre, pourquoi ça peut vous faire une autre question? Si vous êtes inquiet au sujet de la performance, vous vous inquiétez clairement trop tôt puisque vous n'avez pas de code pour le profiler et que vous le découvrez par vous-même. En outre, si Apple ne documente pas ce comportement, il pourrait très bien changer à l'avenir, vous ne devriez donc pas vous y fier. –

+18

Peut-être que j'étais intéressé? – Ian1971

Répondre

36

Il est recalculé. - [NSString hash] est en fait un appel à - [NSCFString hash] (en raison d'un pontage sans frais).

Si vous créez un programme qui appelle - [NSString hash] sur la même chaîne et que vous interrompez les appels et modifiez la mémoire sauvegardant la chaîne, vous obtenez une valeur de hachage recalculée. Cela me dit qu'il n'y a pas de cache impliqué.

(gdb) b -[NSCFString hash] 
Breakpoint 1 at 0x3b02fa3 
(gdb) r 
Breakpoint 1, 0x93652fa3 in -[NSCFString hash]() 
(gdb) c 
Continuing. 
2009-05-13 14:23:39.003 a.out[1754:813] Hash: -327163326 

Notez la valeur de hachage.

Breakpoint 1, 0x93652fa3 in -[NSCFString hash]() 
(gdb) bt   
#0 0x93652fa3 in -[NSCFString hash]() 
#1 0x00001f73 in main() at test.m:10 
(gdb) fra 1 
#1 0x00001f73 in main() at test.m:10 
10  NSLog(@"Hash: %d", [m hash]); 
(gdb) info locals 
pool = (NSAutoreleasePool *) 0x109760 
m = (NSString *) 0x2030 
(gdb) x/20x 0x2030 
0x2030 <dyld__mach_header+32>: 0xa06f54a0 0x000007c8 0x00001fa2 0x00000012 

0xa06f54a0 est le pointeur "isa", 0x00001fa2 est un pointeur sur la chaîne "XXXXX".

(gdb) set {int}0x1fa2 = 0x59595959 

alter la chaîne « xxxxxx » à « YYYYXXXX », puis continuer à le deuxième appel de hachage

(gdb) c 
Continuing. 
2009-05-13 14:24:35.884 a.out[1754:813] Hash: -246144954 

Remarque la valeur de hachage qui est différent sur le aussi loin que ObjC sait chaîne immuable.

Le programme que j'ai (de) Bugged est:

#import <Cocoa/Cocoa.h> 

int main() 
{ 
    NSAutoreleasePool * pool = [NSAutoreleasePool new]; 

    NSString * m = [NSString stringWithString:@"XXXXXXXXXXXXXXXXXX"]; 

    NSLog(@"Hash: %d", [m hash]); 
    NSLog(@"Hash: %d", [m hash]); 

    [pool release]; 
} 
+0

réponse impressionnante. Merci – Ian1971

+0

Très belle réponse –

+11

vous pouvez également regarder le code source pour CFStringRef ici: http://opensource.apple.com/source/CF/CF-476.17/CFString.c Rechercher « CFHashCode __CFStringHash (CFTypeRef cf) pour la fonction appelée. Notez qu'il (a) fait les choses différemment pour les tampons de chaîne 8 bits et Unicode, et (b) ne hache que jusqu'à un certain nombre de caractères (actuellement 96). Recherchez '/ * String hashing:' pour voir les détails du ou des algorithmes de hachage. –

Questions connexes