1. Introdução ao Sonic-RS
sonic-rs é uma biblioteca Rust JSON de alto desempenho baseada em SIMD, que é a versão Rust da biblioteca sonic JSON.
O projeto de código aberto Sonic da Bytedance agora inclui várias bibliotecas JSON em diferentes idiomas (conforme mostrado abaixo). Entre eles, sonic-go foi o primeiro a ser de código aberto, usando tecnologia JIT e SIMD, e sonic-cpp usou modelos C++ e tecnologia SIMD. Ambas as bibliotecas JSON foram implementadas em larga escala dentro do Byte. No contexto de otimização de custos, a fim de ajudar os negócios Golang a migrar para Rust e otimizar o desempenho do Rust JSON, desenvolvemos uma biblioteca JSON de alto desempenho sonic-rs em linguagem Rust pura com base em nossa experiência e prática de otimização JSON.
-
sonic: https://github.com/bytedance/sonic (biblioteca Golang JSON)
-
sonic-cpp: https://github.com/bytedance/sonic-cpp (biblioteca C++ JSON)
-
sonic-rs: https://github.com/cloudwego/sonic-rs (biblioteca Rust JSON)
As funções JSON atualmente suportadas pelo sonic-rs são relativamente completas, basicamente alinhadas com as funções relacionadas do serde-json e fornecem funções mais ricas e interfaces de alto desempenho. As principais características do Sonic-rs são:
-
FastStr
Basicamente compatível com o ecossistema Serde, e também suporta tipos em Volo -
Suporta codificação e decodificação de tipo dinâmico e análise sob demanda
-
Tipos de suporte
LazyVaue
,RawNumber
etc. -
Suporta
UTF-8
precisão de ponto flutuante padrão de soma de verificação
Em termos de desempenho, baseamos-nos na estrutura Rust e nos dados JSON fornecidos pelo benchmark oficial serde-rs ( https://github.com/serde-rs/json-benchmark ) e comparamos serde-json, simd-json e sonic -rs em O desempenho de análise sob a estrutura Rust foi testado e pode-se descobrir que o desempenho do sonic-rs é 1,5 ~ 2 vezes maior que o do simd-json e 2 vezes maior que o do serde-json:
twitter/sonic_rs::from_slice_unchecked
time: [694.74 µs 707.83 µs 723.19 µs]
twitter/sonic_rs::from_slice
time: [796.44 µs 827.74 µs 861.30 µs]
twitter/simd_json::from_slice
time: [1.0615 ms 1.0872 ms 1.1153 ms]
twitter/serde_json::from_slice
time: [2.2659 ms 2.2895 ms 2.3167 ms]
twitter/serde_json::from_str
time: [1.3504 ms 1.3842 ms 1.4246 ms]
citm_catalog/sonic_rs::from_slice_unchecked
time: [1.2271 ms 1.2467 ms 1.2711 ms]
citm_catalog/sonic_rs::from_slice
time: [1.3344 ms 1.3671 ms 1.4050 ms]
citm_catalog/simd_json::from_slice
time: [2.0648 ms 2.0970 ms 2.1352 ms]
citm_catalog/serde_json::from_slice
time: [2.9391 ms 2.9870 ms 3.0481 ms]
citm_catalog/serde_json::from_str
time: [2.5736 ms 2.6079 ms 2.6518 ms]
canada/sonic_rs::from_slice_unchecked
time: [3.7779 ms 3.8059 ms 3.8368 ms]
canada/sonic_rs::from_slice
time: [3.9676 ms 4.0212 ms 4.0906 ms]
canada/simd_json::from_slice
time: [7.9582 ms 8.0932 ms 8.2541 ms]
canada/serde_json::from_slice
time: [9.2184 ms 9.3560 ms 9.5299 ms]
canada/serde_json::from_str
time: [9.0383 ms 9.2563 ms 9.5048 ms]
2. Prática de otimização Sonic-RS
A otimização do sonic-rs é baseada principalmente no SIMD e parte dela baseia-se nas ideias de otimização de outras bibliotecas JSON, como simd-json. SIMD (instrução única, dados múltiplos) é uma tecnologia de otimização paralela que pode processar vários dados em paralelo com uma instrução. A maioria das CPUs hoje já suporta vários conjuntos de instruções SIMD. Por exemplo, SSE, AVX2, AVX512 na arquitetura x86_64, conjunto de instruções neon na arquitetura aarch64, etc. Depois de otimizar usando instruções SIMD, para uma tarefa adequada, o programa executará menos instruções e, portanto, terá melhor desempenho.
Em termos de design geral, sonic-rs não adota a ideia de análise de dois estágios do simd-json. Ele aplica principalmente a otimização SIMD a pontos de acesso na análise e serialização JSON, incluindo serialização de string, análise sob demanda e ponto flutuante. análise de número, espere.
2.1 Serialização de string otimizada para SIMD
A serialização de strings é o ponto quente da serialização JSON. Ao serializar, você precisa verificar a string em busca de caracteres de escape. Para strings mais longas, a operação de julgar caracteres de escape byte por byte é demorada. A verificação de caracteres de escape é muito adequada para acelerar o uso do SIMD.
Se você usar instruções AVX2 para verificar caracteres de escape, conforme mostrado no código a seguir. Este código SIMD está na arquitetura Haswell. Depois que a otimização O3 é ativada, existem apenas seis instruções SIMD, ou seja, 6 instruções SIMD podem varrer 32 bytes por vez. Comparado com o código escalar, o número de instruções do programa é bastante reduzido, reduzindo assim o tempo de execução do programa.
static inline __m256i _mm256_find_quote(__m256i vv) {
__m256i e1 = _mm256_cmpgt_epi8 (vv, _mm256_set1_epi8(-1));
__m256i e2 = _mm256_cmpgt_epi8 (vv, _mm256_set1_epi8(31));
__m256i e3 = _mm256_cmpeq_epi8 (vv, _mm256_set1_epi8('"'));
__m256i e4 = _mm256_cmpeq_epi8 (vv, _mm256_set1_epi8('\\'));
__m256i r1 = _mm256_andnot_si256 (e2, e1);
__m256i r2 = _mm256_or_si256 (e3, e4);
__m256i rv = _mm256_or_si256 (r1, r2);
return rv;
}
2.2 Análise sob demanda de otimização SIMD
Muitos cenários de negócios usam apenas alguns campos em JSON, o que é muito adequado para análise sob demanda e para ignorar campos JSON desnecessários durante a análise. Ao pular campos JSON, a dificuldade está em como pular objetos e matrizes com eficiência em JSON.
Com base nas regras gramaticais que os colchetes de objeto e matriz em JSON devem corresponder, sonic-rs usa SIMD para implementar um algoritmo eficiente de correspondência de colchetes. Primeiro, obtenha o bitmap do objeto json e da matriz por meio do SIMD e, em seguida, pule o objeto e a matriz calculando o número de colchetes. Quando uma correspondência de colchetes é encontrada, o objeto ou matriz pode ser ignorado.
2.3 Análise de número de ponto flutuante otimizado SIMD
A análise de número de ponto flutuante é um ponto importante de desempenho na análise JSON. Dentro dos bytes, descobrimos que as mantissas da maioria dos números de ponto flutuante em JSON são relativamente longas e também adequadas para otimização SIMD. Conforme mostrado abaixo, para uma mantissa de número de ponto flutuante de 16 bytes "1234342112345678":
-
Primeiro leia esta string no registrador vetorial. Neste momento, cada número no vetor ainda é o valor do código ASCII.
-
Em segundo lugar, use a subtração vetorial para subtrair o código ASCII '0' byte por byte para obter v1. Neste momento. Os números em v1 já estão em decimais.
-
Em seguida, continue a usar instruções vetoriais para multiplicar e somar cada número em v1 (multiplique o bit alto por 10 e adicione o bit baixo) para obter v2. Cada número em v2 já é um número decimal de dois dígitos.
-
Por analogia, usando instruções SIMD para acumular camada por camada, a v16 é finalmente obtida. v16 contém um número de 16 dígitos, que é o resultado final da análise de mantissa.
-
Finalmente, usamos instruções vetoriais para converter o tipo v16 para u64.
Todo o processo de análise pode completar a análise da mantissa de ponto flutuante sem percorrer todos os caracteres da mantissa de ponto flutuante.
3. Status e planos do Sonic-RS
sonic-rs é de código aberto há mais de três meses e atualmente está iterado para a versão 0.3. Ele já suporta a versão estável do Rust e a arquitetura aarch64. Sonic-rs acumulou alguns documentos de uso para ajudar os desenvolvedores em todos os aspectos:
-
Golang migra usuários Rust para usar sonic-rs: https://github.com/cloudwego/sonic-rs/blob/main/docs/for_Golang_user_zh.md
-
Migração de usuário Rust serde-json sonic-rs: https://github.com/cloudwego/sonic-rs/blob/main/docs/serdejson_compatibility.md
-
Detalhes de otimização de desempenho: https://github.com/cloudwego/sonic-rs/blob/main/docs/performance_zh.md
No futuro, o sonic-rs continuará a melhorar o desempenho, a facilidade de uso e a estabilidade. Espera-se que ele suporte Bytes/FastStr
a análise de cópia zero de tipos de dados comuns, suporte à detecção de instruções SIMD durante o exercício, etc. .
endereço do projeto
GitHub: https://github.com/cloudwego
Site oficial: www.cloudwego.io
Os recursos piratas de "Celebrating More Than Years 2" foram carregados no npm, fazendo com que o npmmirror tivesse que suspender o serviço unpkg da Microsoft na China fez as malas coletivamente e foi para os Estados Unidos, envolvendo centenas de pessoas . biblioteca de visualização front-end e o conhecido projeto de código aberto ECharts do Baidu - "indo para o mar" para apoiar os golpistas de peixes usaram o TeamViewer para transferir 3,98 milhões! O que os fornecedores de desktop remoto devem fazer? Zhou Hongyi: Não resta muito tempo para o Google. Recomenda-se que todos os produtos sejam de código aberto. Um ex-funcionário de uma conhecida empresa de código aberto deu a notícia: Após ser desafiado por seus subordinados, o líder técnico ficou furioso e. demitiu a funcionária grávida. O Google mostrou como executar o ChromeOS em uma máquina virtual Android. Por favor, me dê alguns conselhos: qual é o papel do time.sleep(6) aqui? A Microsoft responde aos rumores de que a equipe de IA da China está "fazendo as malas para os Estados Unidos" Comentários do People's Daily Online sobre a cobrança semelhante a matryoshka do software de escritório: Somente resolvendo ativamente "conjuntos" podemos ter um futuro