11
votes

Quels meilleurs moyens d'utiliser des décimales et des datetes avec des tampons de protocole?

Je voudrais savoir quelle est la manière optimale de stocker un type de données commun non inclus dans la liste prise en charge par des tampons de protocole.

  • DateTime (précision secondaire)
  • DateTime (Milliseconds Precision)
  • Décimales avec précision fixe
  • Décimales avec une précision variable
  • Beaucoup de valeurs de bool (si vous en avez beaucoup, on dirait que vous aurez 1 à 2 octets surhead pour chacun d'entre eux en raison de leurs balises.

    L'idée est également de les cartographier des types de données C ++ / Python / Java correspondants.


0 commentaires

4 Réponses :


2
votes

Désolé, pas une réponse complète, mais un "moi aussi".

Je pense que c'est une bonne question, une réponse que j'aimerais adorer une réponse à moi-même. L'incapacité à décrire de manière native des types fondamentaux tels que les denttimes et (pour les applications financières) des décimales de point fixes, ou carapez-les à des types spécifiés par la langue ou définie par l'utilisateur, c'est un vrai tueur pour moi. Son plus ou moins m'a empêché de pouvoir utiliser la bibliothèque, que je pense autrement est fantastique.

déclarant que votre propre message "DateTime" ou "fixepoint" dans le proto-grammaire n'est pas vraiment une solution, Comme vous aurez toujours besoin de convertir la représentation de votre plate-forme vers / depuis les objets générés manuellement, ce qui est sujette d'erreur. En outre, ces messages imbriqués sont stockés en tant que pointeurs d'objets alloués à des tas en C ++, qui est extrêmement inefficace lorsque le type sous-jacent est essentiellement juste un entier 64 bits.

Spécifiquement, je voudrais pouvoir être capable. écrire quelque chose comme celui-ci dans mes fichiers de proto: xxx

et je serais tenu de fournir quelle que soit la colle nécessaire pour convertir ces types à / de la méthode fixe64 et INT64 afin que la sérialisation travaillerait. Peut-être que quelque chose comme Adobe :: Promouvoir ?


0 commentaires

3
votes

Voici quelques idées basées sur mon expérience avec un protocole de fil similaire aux tampons de protocole.

DateTime (précision des secondes)

DateTime (précision millisecondes)

Je pense que la réponse à ces deux serait la même, vous feriez généralement de la même manière avec une plus petite gamme de chiffres dans le cas de la précision des secondes.

Utilisez un SINT64 / SFIXED64 pour stocker le décalage en secondes / millisecondes d'une époque bien connue comme minuit GMT 1/1/1970. Voilà comment la date d'objets est représenté dans Java . Je suis sûr qu'il y a des analogues en Python et C ++.

Si vous avez besoin d'informations sur le fuseau horaire, passez autour de votre date / fois en termes d'UTC et de modéliser le fuseau horaire pertinent comme champ de chaîne distinct. Pour cela, vous pouvez utiliser les identifiants du Base de données Olson ZoneInfo depuis que cela est devenu un peu Standard.

De cette façon, vous avez une représentation canonique pour la date / l'heure, mais vous pouvez également localiser avec n'importe quel fuseau horaire pertinent.

Décimales avec précision fixe

Ma première pensée consiste à utiliser une chaîne similaire à la manière dont on construit des objets décimaux de l'emballage décimal de Python. Je suppose que cela pourrait être inefficace par rapport à une représentation numérique.

Il peut y avoir de meilleures solutions en fonction du domaine avec lequel vous travaillez. Par exemple, si vous modélisez une valeur monétaire, vous pouvez peut-être vous éviter à l'aide d'un UINT32 / 64 pour communiquer la valeur en centimes par opposition à des quantités de dollars fractionnaires.

Il y a aussi quelques suggestions utiles dans ce fil .

Décimales avec une précision variable

Les tampons de protocole ne supportent pas déjà cela avec des types de flotteurs flottants / doubles? Peut-être que j'ai mal compris ce point de balle.

Quoi qu'il en soit, si vous avez besoin de faire le tour de ces types scalaires, vous pouvez encoder à l'aide de IEEE-754 à UINT32 ou UINT64 (float vs double respectivement). Par exemple, java Permet Vous devez extraire la représentation IEEE-754 et vice versa de flotteur / double objets. Il existe des mécanismes analogues en C ++ / Python.

beaucoup de valeurs de bool (si vous avez beaucoup d'entre eux on dirait que vous aurez 1-2 octets au-dessus de la tête pour chacun d'eux en raison de leurs tags.

Si vous êtes préoccupé par les octets gaspillés sur le fil, vous pouvez utiliser Techniques de masquage bit pour compresser beaucoup booléens dans un seul UINT32 ou UINT64.

Parce qu'il n'ya pas de support de première classe dans des tampons de protocole, toutes ces techniques nécessitent un contrat d'un peu de gentlemens entre les agents. Peut-être utiliser une convention de dénomination sur vos champs tels que "_DTTM" ou "_mask" aiderait à communiquer lorsqu'un champ donné a une sémantique codant supplémentaire au-delà du comportement par défaut des tampons de protocole.


0 commentaires

3
votes

La mission de conception Protobuf est la plus susceptible de conserver le support de type de données comme possible que possible, de sorte qu'il est facile d'adopter de nouvelles langues à l'avenir. Je suppose qu'ils pouvaient fournir des types de messages de construction, mais où dessinez-vous la ligne?

Ma solution consistait à créer deux types de message: xxx

ceci est uniquement parce que je viens d'un fond C #, où ces types sont pris pour acquis.

dans Retrospect, Timespan et DateTime a peut-être été surchargé, mais il s'agissait d'une manière "bon marché" d'éviter la conversion de H / M / S à S et inversement ; Cela dit, il aurait été simple de simplement implémenter une fonction utilitaire telle que: xxx

bklyn, a souligné que la mémoire de tas est utilisée pour les messages imbriqués; Dans certains cas, cela est clairement très valide - nous devrions toujours être conscients de la manière dont la mémoire est utilisée. Mais, dans d'autres cas, cela peut être moins préoccupant, où nous sommes inquiétés davantage sur la facilité de mise en œuvre (c'est la philosophie Java / C #, je suppose).

Il existe également un petit inconvénient d'utiliser non Types intrinsèques avec le protobuf TextFormat :: Imprimante ; Vous ne pouvez pas spécifier le format dans lequel il est affiché, il ressemble donc à quelque chose comme: xxx

... qui est trop verbeux pour certains. Cela dit, il serait plus difficile de lire si c'était représenté en quelques secondes.

pour conclure , je dirais:

  • Si vous êtes inquiet pour l'efficacité de la mémoire / analyse, utilisez des secondes / millisecondes.
  • Toutefois, si la facilité de mise en œuvre est l'objectif, utilisez des messages imbriqués ( DateTime , etc.).

0 commentaires

1
votes

Pour DateTime avec une résolution Millisecond, j'ai utilisé un int64 qui a la dateTime comme yyyymmddhhmmssmm . Cela le rend à la fois concis et lisible, et surprenant, durera très longtemps.

Pour les décimales, j'ai utilisé octet [] , sachant qu'il n'y a pas de meilleure représentation qui ne sera pas une perte.


0 commentaires