Conversion NSString en NSData (optimisation)

rarimrarim Membre
juin 2016 modifié dans Objective-C, Swift, C, C++ #1

Hi !


 


Mon problème est simple, je dois pouvoir faire entrer une chaine de caractère de plus de 16 caractères dans un slot de 16 octets.


 


 


Tout fonctionne très bien pour un caractère par octet (16 caractères ou moins) mais je cherche à  optimiser l'espace afin de pouvoir entrer une chaine de caractère plus longue. 


 


Je procède comme ceci :



NSString * newStr = @hello world;
unichar buffer[newStr.length];
[newStr getCharacters:buffer];

UInt8 byteArray [16] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};

for (NSUInteger i = 0; i < newStr.length ; i++)
{      
if(i >= 15)      
break;
                      
byteArray[i] = buffer[i];
}
NSMutableData * data = [[NSMutableData alloc]initWithBytes:byteArray length:16];

Merci 


Réponses

  • klogklog Membre
    juin 2016 modifié #2

    J'espère ne pas dire de bêtises, mais un unichar c'est du 16 bits, non ?... Et j'imagine que ton name8 c'est du 8 bits... 


     


    Sinon, si ta chaine ne contient que de l'ASCII, tu peux gagner 1 bit par caractères, car seuls les 128 premiers sont utiles (de mémoire).


    Si tu restreins encore le champ des caractères, en ne prenant par exemple qu'un sous-ensemble de caractères, tu peux faire une table de conversion de ces caractères "utiles" en n'utilisant que 5 ou 6 bits.


     



    Après tu concatènes tes morceaux de bits dans ta table de 16 octets.



     

    Tu peux aussi compresser ta chaà®ne s'il y a de nombreux caractères répétitifs.


  • MalaMala Membre, Modérateur
    juin 2016 modifié #3


    Après tu concatènes tes morceaux de bits dans ta table de 16 octets.


     

    Tu peux aussi compresser ta chaà®ne s'il y a de nombreux caractères répétitifs.




    Il faut vraiment faire gaffe aux données d'entrée. Il y a pas mal d'extensions ASCII qui exploitent le dernier bit...


    https://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange


     


    Après compresser, je vois pas trop comment vu le peu d'octets à  traiter. Le rendement va être négatif.


     


    Par contre, les gars faite preuve d'un peu d'imagination pour coder vos bidules. Faire une boucle lorsqu'une simple copy de buffer (memcpy) suffit c'est pas top.


    Edit: non j'ai rien dit pour la copie vu que c'est de l'unichar (unsigned short) en entrée pardon.


  • klogklog Membre
    juin 2016 modifié #4


    Il faut vraiment faire gaffe aux données d'entrée. Il y a pas mal d'extensions ASCII qui exploitent le dernier bit...


    https://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange




     


    Yep, mais pas nécessairement pour des trucs expressifs.... S'agit de voir si la partie supérieur contient des éléments utiles ou non.


     


     





    Après compresser, je vois pas trop comment vu le peu d'octets à  traiter. Le rendement va être négatif.




     


    Ca c'est probable oui !  :D


  • Le contenu de la chaine de caractères est totalement aléatoire (saisie utilisateur) ou comporte des données récurrentes ?


  • MalaMala Membre, Modérateur


    Yep, mais pas nécessairement pour des trucs expressifs.... S'agit de voir si la partie supérieur contient des éléments utiles ou non.




    Vu le peu qu'on sait je préfère être restrictif. Ce serait pas le coup qu'il vienne nous demander de faire marcher le SAV pour du debug...  xd

  • PyrohPyroh Membre
    juin 2016 modifié #7

    Si tu utilise l'ASCII US (7bits) tu vas gagner 2 caractères par chaines en sachant que tu ne peux stocker que les 127 premiers caractères de l'ASCII.


     


    Tu peux t'inspirer du code Baudot et coder sur 5 bits. Tu as deux plages de 31 caractères et une valeur qui te permet de passer d'une aÌ€ l'autre.


    Au lieu d'utiliser le code tel quel tu peux faire comme suit :


    0x00 est le signal de changement de plage.


     


    Première plage:


    0x01 - 0x1A : a-z


    0x1B - 0x1F : Les 5 lettres les plus utilisées dans le langage en majuscule.


     


    Deuxième plage:


    0x01 - 0x15 : Le reste des majuscules


    0x16 - 0x1F : 0-9


     


    Pour l'espace un enchainement de deux 0x00. Tu trim les espaces en fin de chaine pour être tranquille.


    Au final tu peux caser dans l'idéal (rester sur la première plage sans utiliser d'espace) 25 caractères soit 9 de mieux.


     


    Mais ça reste super restrictif, reste à  voir ce que tu veux stocker la dedans...


     


    En utilisant directement 6bits tu as 2 possibilités en plus vu que tu n'as plus de valeur réservée et tu te retrouve avec [a-z][A-Z][0-9][space][dot] et sur 128bit tu case 22 caractères soit 6 de plus.  


Connectez-vous ou Inscrivez-vous pour répondre.