10
votes

Meilleur moyen de créer des tableaux de gros bits à Lua

Je veux lire un gros fichier binaire (1Mb de taille) en mémoire à l'aide de Lua. Le périphérique cible est mobile, donc je veux beaucoup minimiser l'empreinte mémoire.

à partir d'un look rapide en ligne, il semble que les tables Lua utilisent 16B pour chaque index entier séquentiel (clé) plus l'espace pour stocker la valeur, que, comme je stocke des données binaires, j'utilise seulement 2 bits, mais permettant simplement de dire 1 octet.

pour les enregistrements 1E6 qui seront 1E6 * 17 = ~ 17 Mo - qui est énorme!

de ma brève lecture Il semble que je puisse utiliser userData pour implémenter tout ce que je veux dans C. Je n'ai pas utilisé c avant, mais il semble qu'il utiliserait

1b * 1e6 = 125kb

Dois-je faire ceci ou ai-je eu quelque chose de très faux / est-il un moyen plus facile de le faire?

Des conseils ou même des noms de nom pour les calculs de merde sont les bienvenus :)

Edit: quelques réponses intéressantes ci-dessous sur la conservation des données dans une chaîne (merci!) et utiliser des OP bitwise. Je viens de venir accrocher un exemple dans le livre PIL (3e édition PG293) qui compare les tableaux de stockage de booléens en C afin qu'ils utilisent 3% de la mémoire. Bien que cela soit cool et utile, cela peut être surchargé pour moi, car les solutions ci-dessous suggèrent que je peux vous adapter à 1 Mo, ce qui va bien pour moi.

EDIT: est venu sur Ceci c blob implique

EDIT: Solution - Je lis le contenu du fichier dans une chaîne comme suggéré et que je l'utilise à l'aide de 5,1, il a dû utiliser une 3ème partie Bit Op Lib - je suis allé avec une implémentation pure Lua Luabit . Merci tout le monde !!


12 commentaires

Que voulez-vous faire avec les données une fois que c'est dans l'environnement Lua?


Utilisez-le pour vérifier les données en effectuant plusieurs hayes sur des chaînes entrantes et en vérifiant la matrice (filtre de fleurs Aka) en.wikipedia .org / wiki / bloom_filter


Je ne sais pas que c'est une bonne idée de Lua, il a déjà atteint les chaînes, et si vous ne travaillez que avec UserData, vous ne pouvez absolument rien faire du tout avec elle à moins que vous ne puissiez pas implémenter vous-même. Donc, vous pouviez sauter le milieu et faire tout dans C.


Merci pour votre réponse. Eh bien, je ne ferai pas réellement stocker des cordes - le filtre de floraison représentera des mots en retournant des bits dans la matrice. validation. Avoir un sens?


Chaque chaîne qui pénètre dans l'environnement Lua est hachée. Peu importe si vous le stockez. Cela signifie "a" == "b" compare effectivement les hatupes pas des chaînes. Pour hacher une chaîne, vous devez le lire, le lire avec Lua, il doit entrer dans l'environnement Lua et chaque fois que vous obtenez une sous-chaîne ceci crée une nouvelle chaîne hachée par Lua.


Merci pour le commentaire. Je vais effectuer un hachage personnalisé sur les données de charme pour vérifier le filtre de floraison - dans mon esprit, il est irréel que les chaînes sont stockées à Lua - cette approche doit fonctionner dans n'importe quel environnement prenant en charge des caractères et des tableaux de bits tant que le même codage est utilisé pour convertir les caractères en INT lors de l'exécution du hachage. S'il vous plaît dites-moi si je manque quelque part


Ce qui vous manque, c'est la performance. Je ne vous dirais pas si vous n'aviez pas mentionné que c'est pour un environnement mobile. Hachage une fois - ok bien, ne peut pas faire sans. Hachage deux fois - pas une bonne idée. Aussi Lua ne prend pas en charge les tableaux de bit, pas beaucoup de langues (avez-vous voulu dire byte matrices peut-être?)


par un tableau de morceaux, je veux dire un bool []. Tout ce que je veux faire, c'est vider les données binaires "01010101 ..." dans une structure de données que je peux alors interroger dans le formulaire est le bit à index x true ou quelque chose de similaire


Comme je l'ai dit avant. Implémentez le hachage dans C. Si vous souhaitez traiter plus loin dans Lua, vous pouvez toujours mettre le résultat dans une userData avec une métabilité qui permet d'accéder à une matrice, même au niveau du bit.


Je n'imagine vraiment pas que les frais généraux causés par un couple de hashes sur une ficelle de Lua vaut la peine d'être implémentés dans C! Ce ne sera qu'une chaîne toutes les quelques quelques secondes.


Vous avez écrit environ 1 Mo de fichiers dans votre texte de questions;)


Désolé - c'est des données de filtre de fleurs précalisées I.E. 1001010101, etc pas les données de chaîne! Thx pour les commentaires :)


3 Réponses :


8
votes

Vous pouvez stocker une grosse blob de la chaîne de Lua, elle fonctionnera avec toutes les données binaires. Maintenant, la question est de savoir ce que vous voulez faire avec les données. De quelque manière que ce soit, vous pouvez utiliser string.byte à Extrayez tout octet individuel et utilisez Lua's Bitt32 bibliothèque pour descendre aux bits . (Pour Lua de 5,1 ans et plus, vous devez soit écrire vos propres routines C, utiliser un package tiers.)


5 commentaires

Vous pouvez extraire des octets individuels en tant que nombres avec string.byte . Vous pouvez manipulations de biotes avec la bibliothèque bit32 .


Grand merci. Comment stockez-vous un blob dans un type de chaîne à l'aide de Lua - je ne peux pas voir de Googling!


Je regarderais le manuel au lieu de googling :-) Utilisez Fichier: Lire '* A' Pour lire le fichier complet ou Fichier: Lire (n) pour lire N octets.


Du manuel, il devrait être clair que dans Lua, le type de chaîne est une séquence comptée d'octets. Il n'y a pas de limitations de contenu sur elle comme dans de nombreuses autres langues.


Je suppose qu'il serait préférable de stocker mes données binaires dans le fichier plutôt que comme un fichier texte qui est ce que je fais actuellement!



3
votes

Vous pouvez stocker les données dans une chaîne et le manipuler avec la bibliothèque de chaînes et Lua Bitop

La bibliothèque Bit32 intégrée de Lua5.2 est préférée si disponible.


0 commentaires

1
votes

Si vous souhaitez lire 1 Mo en mémoire, vous ne vous retrouverez pas avec 250 Ko ...

Si vous lisez le fichier dans une chaîne Lua, vous vous retrouvez avec 1 Mo, car les chaînes Lua ne sont que des octets propres de 8 bits.

Après cela, vous pouvez traiter les données en fonction de sa structure, en utilisant peut-être le Bibliothèque de structure .


6 commentaires

Si je suis en train de lire à partir d'un fichier TXT avec UTF-8 codant dans une matrice binaire / bool, il serait (s'il vous plaît corriger si je me trompe que je pourrais très bien être!). J'imagine que UTF-8 est utilisé, il ne se soucie pas que son seul stockage de données binaires mais qu'il utilise toujours 8 bits par charret non compressé.


Je vois ce que tu veux dire - j'ai fait le calcité dans le commentaire ci-dessus en utilisant 8 octets par caractère dans une chaîne, pas 8 bits, THX


Si votre source est du texte UTF-8, je voudrais définitivement considérer que pour être binaire . Votre deuxième phrase n'a pas beaucoup de sens pour moi: s'il n'y a que "uniquement des données binaires" dans le fichier, comment peut-il être codé UTF-8?


Ah Ok, alors peut-être que c'est mon malentendu ici. Dans mon esprit, un fichier texte utilise généralement un codage 8 bits par défaut pour les caractères anglais. Disons que nous utilisons UTF-8, simplement parce que les données de caractères réelles sont binaires (ce qui signifie soit un «0» ou un «1»), je penserais qu'il utiliserait toujours des caractères de 8 bits pour le représenter. Par ceci, je veux dire un fichier texte avec le contenu "0101"> = 4x8bits (4 octets) alors qu'un réseau booléen en mémoire pourrait stocker ces mêmes données dans 4 bits, donc le tableau de bits doit être d'environ 1/8 de la taille du fichier texte que contient des données binaires. Ai-je tort?


Je suppose que si je lisez les données de chaîne dans Lua et que je le stocke comme une chaîne, il prendra exactement le même espace Oui - mais je souhaite stocker convertir les chaînes en données d'octet réelles - donc si j'ai "01010101" dans le fichier texte cela prendrait 1 octet de Mem à Lua


Dupliquer de mon commentaire ci-dessus mais cela ferait beaucoup plus de sens si j'avais stocké mes données binaires brutes dans le fichier au lieu de la stocker en tant que fichier texte!