Pergunta

Eu preciso para serializar um valor .NET DateTime em uma mensagem de buffers de protocolo.

Meu plano é usar o DateTime.ToBinary () e, em seguida, passar o valor retornado de 64 bits na mensagem. Mas eu não tenho certeza do que escolher como um tipo de dados buffers de protocolo para representar isso.

Acho que estou confuso sobre quando o fixed64 (ou sfixed64) tipos de dados deve ser utilizado.

Estou assumindo neste cenário que eu usaria os tipos assinados desde os valores retornados por DateTime.ToBinary () pode ser negativo, bem como positiva.

Foi útil?

Solução

Bem, você quer definitivamente quer int64 ou sfixed64 para lidar com o valor a ser assinado.

Depois de ter feito apenas um teste rápido, DateTime.Now.ToBinary() é codificado em 10 bytes utilizando int64 enquanto sfixed64 sempre usará 8 bytes. Basicamente, a codificação de comprimento variável é grande para pequenos números, mas torna-se maior do que a codificação fixa para grandes números. (É o mesmo tipo de troca como usando UTF-8 em vez de UTF-16 - caracteres ASCII pode ser codificado em UTF-8 em um único byte, mas mais tarde em pontos de código acabar por ser codificado como 2 e, em seguida, 3 bytes, enquanto UTF -16 sempre usa 2 bytes para caracteres na BMP).

Meu palpite é que os valores DateTime.ToBinary() são provável para ser muito grande (sem conhecer os detalhes de exatamente o que ele faz) para sfixed64 é mais adequado.

Isso faz sentido?

Outras dicas

Na protobuf-net , eu uso uma abordagem escala graduada (e de fato , ele lida com tudo isso para você, se você simplesmente usar DateTime) - o .proto equivalente é algo como isto:

message DateTime {
  optional sint64 value = 1; // the offset (in units of the selected scale)
                             // from 1970/01/01
  optional TimeSpanScale scale = 2 [default = DAYS]; // the scale of the
                                                     // timespan
  enum TimeSpanScale {
    DAYS = 0;
    HOURS = 1;
    MINUTES = 2;
    SECONDS = 3;
    MILLISECONDS = 4;

    MINMAX = 15; // dubious
  }
}

i. se o DateTime pode ser expresso em dias inteiros, eu só enviar o número de dias desde 1970, etc - além de um pequeno marcador para a escala. Isto significa que as datas podem ser enviados um pouco mais eficiente, mas ele realmente não custam muito mais para outras escalas.

Pessoalmente, eu não iria usar ToBinary() - Eu explicitamente usar um deslocamento de uma escala conhecida de uma época conhecida (tais como a época unix). Isso torna mais portátil entre plataformas. Mas se você está enviando (por exemplo) apenas o milissegundo offset, em seguida, uma escala fixa normalmente seria mais eficiente do que uma escala variante de comprimento. Se você precisa de sinal ou sem sinal depende se você precisa de datas antes de sua época ;-p

Você deve usar um número de 64 bits assinado, não porque o DateTime pode ser negativo, mas porque o método ToBinary retorna um Int64, que é um número de 64 bits assinado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top