Ispirato da this question. Ho creato un piccolo programma di benchmark per confrontare ProtoBuf, BinaryFormatter e Json.NET. Lo stesso benchmark è una piccola console basata su https://github.com/sidshetye/SerializersCompare. Aggiunta gratuita per aggiungere/migliorare, è abbastanza semplice aggiungere un nuovo serializzatore al mix. In ogni caso, i miei risultati sono i seguenti:Perché ProtoBuf è così lento durante la prima chiamata ma molto veloce nei loop interni?
Binary Formatter ProtoBuf Json.NET ServiceStackJson ServiceStackJSV
Loop Size:512 bytes Size:99 bytes Size:205 bytes Size:205 bytes Size:181 bytes
1 16.1242 ms 151.6354 ms 277.2085 ms 129.8321 ms 146.3547 ms
2 0.0673 ms 0.0349 ms 0.0727 ms 0.0343 ms 0.0370 ms
4 0.0292 ms 0.0085 ms 0.0303 ms 0.0145 ms 0.0148 ms
8 0.0255 ms 0.0069 ms 0.0017 ms 0.0216 ms 0.0129 ms
16 0.0011 ms 0.0064 ms 0.0282 ms 0.0114 ms 0.0120 ms
32 0.0164 ms 0.0061 ms 0.0334 ms 0.0112 ms 0.0120 ms
64 0.0347 ms 0.0073 ms 0.0296 ms 0.0121 ms 0.0013 ms
128 0.0312 ms 0.0058 ms 0.0266 ms 0.0062 ms 0.0117 ms
256 0.0256 ms 0.0097 ms 0.0448 ms 0.0087 ms 0.0116 ms
512 0.0261 ms 0.0058 ms 0.0307 ms 0.0127 ms 0.0116 ms
1024 0.0258 ms 0.0057 ms 0.0309 ms 0.0113 ms 0.0122 ms
2048 0.0257 ms 0.0059 ms 0.0297 ms 0.0125 ms 0.0121 ms
4096 0.0247 ms 0.0060 ms 0.0290 ms 0.0119 ms 0.0120 ms
8192 0.0247 ms 0.0060 ms 0.0286 ms 0.0115 ms 0.0121 ms
responsabilità:
I risultati di cui sopra sono all'interno di un Windows VM - i valori/cronometro per gli intervalli molto piccoli potrebbero non essere accurato al 100% rispetto ai sistemi operativi bare metal. Quindi ignora i valori ultra bassi nella tabella sopra.
Per ServiceStack, JSON e JSV sono stati presi da due serie separate. Dal momento che essi condividono la stessa libreria ServiceStack sottostante, in esecuzione uno dopo l'altro colpisce il "avviamento a freddo" punteggi 1 ciclo per la successiva esecuzione (è 'avvio a caldo' veloci)
BinaryFormatter è il più grande in termini di dimensioni, ma anche il più veloce per una singola serializzazione => ciclo di deserializzazione. Tuttavia, una volta eseguito il ciclo di serializzazione => codice di deserializzazione, ProtoBuf è super veloce.
Domanda n. 1: Perché ProtoBuf è molto più lento per una singola serializzazione => ciclo di deserializzazione?
Domanda n. 2: Da una prospettiva pratica, cosa possiamo fare per superare quella "partenza a freddo"? Esegui almeno un oggetto (di qualsiasi tipo) attraverso di esso? Esegui ogni tipo di oggetto (critico) attraverso di esso?
Forse potresti provare a pre-compilare il tuo programma. Per questo, dovrai aggiungere un nome sicuro al binario ed eseguire ngen. – jpa
@jpa "pre-compilazione" e "aggiungi un nome sicuro" sono due soggetti in gran parte non collegati ... –
@MarcGravell, IIRC se si utilizza ngen per precompilare un binario .NET nella cache di assembly globale, funziona solo con un nome forte Ma ovviamente ci sono altri modi per ottenere lo stesso risultato. – jpa