Un fichier binaire contient des données tabulaires.
Il a 144 octets par ligne,
La première colonne est un horodatage de 8 octets en millisecondes,
Chaque colonne suivante est divisée par 4 octets.
L’essentiel est que ce qui suit ne sert qu’à extraire les données de certaines colonnes.

J'ai écrit un JSL qui peut lire des données, mais il est plus lent.
Demandez à un expert de vous aider à résoudre ce problème.
co = 144;
bb = Load Text File( file, blob() );
gs = 9;
m = 0;
g = 1;
k = 1;
ar = [];
ar = J( z, g + gs, . );//20230815
For( k = 1, k <= z, k++,
ff = Blob Peek( bb, (k - 1) * co + 0, 8 );
a = "";
Try( a = Blob To Matrix( ff, "uint", 8, "little", 8 )[1] );
no = Length( Char( a ) );
If( no > 0,
Try(
nn = Format( a / 1000 + Informat( "01/01/1970", "mm/dd/yyyy" ) + In Hours( 8 ), "yyyy-mm-ddThh:mm:ss" );
b = Num( Munger( nn, 12, 2 ) || Munger( nn, 15, 2 ) || Munger( nn, 18, 2 ) );
);
If( 91500 <= b < 92600,
m = m + 1;
ar[m, 1] = Num( Munger( nn, 1, 4 ) || Munger( nn, 6, 2 ) || Munger( nn, 9, 2 ) );
ar[m, 2] = b;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 64, 4 );
ar[m, g + 2] = Blob To Matrix( ff, "int", 4, "little", 1 )[1] / 1000/*BM1*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 68, 4 );
ar[m, g + 3] = Blob To Matrix( ff, "int", 4, "little", 1 )[1] / 1000/*BM2*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 84, 4 );
ar[m, g + 4] = Blob To Matrix( ff, "int", 4, "little", 1 )[1]/*BL1*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 88, 4 );
ar[m, g + 5] = Blob To Matrix( ff, "int", 4, "little", 1 )[1]/*BL2*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 104, 4 );
ar[m, g + 6] = Blob To Matrix( ff, "int", 4, "little", 1 )[1] / 1000/*MM1*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 108, 4 );
ar[m, g + 7] = Blob To Matrix( ff, "int", 4, "little", 1 )[1] / 1000/*MM2*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 124, 4 );
ar[m, g + 8] = Blob To Matrix( ff, "int", 4, "little", 1 )[1]/*ML1*/;
i = 1;
ff = Blob Peek( bb, (k - 1) * co + 128, 4 );
ar[m, g + 9] = Blob To Matrix( ff, "int", 4, "little", 1 )[1]/*ML2*/;
);
,
Break()
);
);
Merci les experts !
Qu'est-ce qui est le plus rapide ? À quelle vitesse cela devrait-il être ?
Utilisez le profileur JSL pour trouver les points chauds.
Le profileur affichera probablement les fonctions blobpeek et blobtomatrix en rouge très vif. Il semble qu'elles soient appelées des millions de fois pour des blobs de 4 octets.
Essayez plutôt ceci : effectuez un appel géant à blobtomatrix pour convertir l'intégralité du fichier en entiers de quatre octets. Cela ne devrait prendre que quelques secondes. Utilisez les opérations matricielles de JMP pour extraire les données dont vous avez besoin. Vous pouvez probablement effectuer la conversion complète sans aucune boucle for.
Si nécessaire, vous pouvez créer une autre matrice géante d'entiers, d'uints et de flottants de 4 ou 8 octets. Utilisez uniquement les colonnes contenant les données binaires correctes. Je combinerais probablement simplement deux entiers de 4 octets pour créer la valeur de 8 octets, quelque chose comme x[row,1] + ( x[row,2]*(2^32) ). Je n'ai pas étudié ce que vous faisiez avec eux, donc ce n'est peut-être pas ce dont vous avez besoin.
De plus : lorsque vous utilisez blobtomatrix pour des entiers de 8 octets, JMP ne pourra conserver que 52 des 64 bits. Étant donné que les colonnes 6 et 7 sont nulles et correspondent aux bits de poids fort d'un nombre little-endian de 8 octets, cela fonctionnera probablement correctement. (Un nombre à virgule flottante double précision ne comporte que 52 bits de fraction.)
Merci Craig!
Comme les données au début du fichier sont incomplètes, j'ai pris le contenu de la dernière ligne
Ce code est utilisé pour deux divisions et deux blobs vers Matrix
Je crois que oui.


Bien ! Je parie que c'était beaucoup plus rapide aussi ! Pas une seule boucle en JSL, toutes les boucles sont internes en C++ où c'est rapide.
Pour tous ceux qui cherchent et se posent des questions :
2 : lit l'intégralité du fichier dans un blob.
3 : convertit l'ensemble du blob en une matrice. En particulier, la matrice comporte 36 colonnes provenant des données binaires d'origine qui avaient 144 octets par ligne ; les valeurs sont toutes des entiers de 4 octets. 144/4=36.
4 : z semble inutilisé ; je *pense* qu'il peut être d'environ 20 millions.
5-16 : crée les colonnes du tableau de données.
18-19 : ces déclarations d'apparence innocente saisissent de hautes colonnes de données de la matrice.
20 : tentative de création d'un entier de 64 bits à partir de deux entiers de 32 bits, voir les commentaires précédents sur 52 bits. Encore une fois, il s'agit d'une colonne entière en une seule étape.
21-30 : copier et transformer des colonnes entières de la matrice vers le tableau.
C'est plutôt cool car il n'y a pas de valeurs à virgule flottante ou de texte dans les données. Les flottants peuvent être traités avec une deuxième matrice de 4 ou 8 flottants. Le texte est plus difficile mais toujours possible ; différents choix en fonction des jeux de caractères 7 bits, 8 bits, Unicode et de la longueur fixe ou des variations de chaînes de longueur variable.
C'est beaucoup plus rapide.
Merci pour le conseil de l'expert.
L'horodatage d'origine de 8 octets peut être converti comme ceci.