---
title: 'Penyimpanan Cache & Kinerja'
description: "Parsing schema JSON adalah operasi yang mahal. Jika Anda menggunakan schema yang sama untuk beberapa evaluasi (misalnya, memvalidasi ribuan rekor atau menangani permintaan web throughput tinggi), Anda harus menghindari parsing ulang schema setiap saat."
navigation:
  icon: 'i-ph-book-open'
seo:
  title: 'Penyimpanan Cache & Kinerja'
  description: "Parsing schema JSON adalah operasi yang mahal. Jika Anda menggunakan schema yang sama untuk beberapa evaluasi (misalnya, memvalidasi ribuan rekor atau menangani permintaan web throughput tinggi), Anda harus menghindari parsing ulang schema setiap saat."
---

`json-eval-rs` dirancang untuk performa tinggi, terutama dalam skenario di mana schema berukuran besar atau sering digunakan kembali. Dua fitur utama memungkinkan hal ini: **Global Schema Caching** dan **MessagePack Serialization**.

## Global Schema Caching

Library ini menyediakan **ParsedSchemaCache** global yang aman untuk multi-thread (thread-safe).

### Konsep

1.  **Parse Sekali**: Anda melakukan parsing string schema sekali dan memberikan `cache_key` yang unik.
2.  **Simpan**: Struktur schema yang sudah di-parse, dikompilasi, dan dioptimalkan disimpan dalam cache global.
3.  **Gunakan Kembali**: Evaluasi selanjutnya cukup merujuk ke `cache_key`. Engine akan membuat instansi ringan yang berbagi data schema berat yang bersifat baca-saja (read-only) dari cache.

### Penggunaan

::code-group
  ```rust [Rust]
  use json_eval_rs::{JSONEval, ParsedSchema, PARSED_SCHEMA_CACHE};
  use std::sync::Arc;

  // 1. Isi cache terlebih dahulu (misalnya, saat startup)
  let schema_json = r#"{...}"#;
  let parsed = ParsedSchema::parse(schema_json).unwrap();
  PARSED_SCHEMA_CACHE.insert("user_schema".to_string(), Arc::new(parsed));

  // 2. Penggunaan kembali secara efisien
  let cached = PARSED_SCHEMA_CACHE.get("user_schema").unwrap();
  let mut eval = JSONEval::with_parsed_schema(cached.clone(), None, Some(data1))?;
  eval.evaluate(data1, None)?;

  let mut eval2 = JSONEval::with_parsed_schema(cached.clone(), None, Some(data2))?;
  eval2.evaluate(data2, None)?;
  ```
  ```csharp [C#]
  // 1. Buat instansi "Template" untuk mengisi cache
  // Constructor secara otomatis melakukan parsing dan dapat memverifikasi schema (opsional)
  using (var template = new JSONEval(schemaJson)) {
     // Di C#, caching dikelola secara internal oleh inti Rust,
     // namun Anda dapat menggunakan FromCache secara eksplisit jika memiliki mekanisme
     // untuk meregistrasi schema terlebih dahulu (penggunaan lanjutan).
     //
     // Pola umum: Parse sekali, simpan instansi jika memungkinkan.
     // Atau gunakan FromCache jika sisi native sudah diinisialisasi sebelumnya.
  }

  // 2. Gunakan kembali instansi yang efisien
  using (var eval = JSONEval.FromCache("my_schema_key")) {
      eval.Evaluate(data);
  }
  ```
  ```typescript [React Native]
  import { JSONEval } from "@json-eval-rs/react-native";

  // 1. Instansiasi yang efisien merujuk pada schema yang di-cache
  // (Memerlukan schema untuk dimuat terlebih dahulu di lingkungan WASM/Native)
  const eval = JSONEval.fromCache('user_schema');
  await eval.evaluate({ data });
  ```
  ```typescript [Web / NodeJS]
  import { JSONEval } from "@json-eval-rs/node"; // atau /bundler, /vanilla

  // 1. Instansiasi yang efisien merujuk pada schema yang di-cache
  const eval = JSONEval.fromCache('user_schema');
  await eval.evaluate({ data });
  ```
::

> **Catatan**: Untuk C# dan binding lainnya, API `FromCache` mengasumsikan schema telah terdaftar di cache global Rust. Saat ini, cara paling umum untuk mengisi cache ini adalah melalui panggilan inisialisasi spesifik atau dengan memastikan schema dimuat sekali melalui pola "loader" jika didukung oleh versi binding Anda.

## MessagePack Serialization

Serialisasi/deserialisasi JSON standar dapat menjadi hambatan (bottleneck). `json-eval-rs` mendukung **MessagePack** (format serialisasi biner) untuk secara drastis mengurangi overhead saat melewati batas FFI (Rust <-> JS/C#).

### Optimasi Zero-Copy

Saat Anda memuat schema melalui MessagePack, atau mengambil schema yang telah dievaluasi sebagai MessagePack:
*   **Ukuran Lebih Kecil**: MessagePack lebih ringkas daripada string JSON.
*   **Pemrosesan Lebih Cepat**: Parsing biner secara signifikan lebih cepat daripada parsing teks.
*   **Zero-Copy (Internal)**: Library menggunakan optimasi untuk meminimalkan penyalinan memori saat menangani data biner antara Rust dan bahasa host.

### Penggunaan

::code-group
  ```csharp [C#]
  // Ambil hasil sebagai byte MessagePack
  byte[] resultBytes = eval.GetEvaluatedSchemaMsgpack();

  // Buat/Muat ulang dari MessagePack
  byte[] schemaBytes = ...; // Schema MessagePack Anda yang sudah dikompilasi sebelumnya
  eval.ReloadSchemaMsgpack(schemaBytes);
  ```
  ```typescript [React Native]
  const schemaMsgpack = new Uint8Array([...]); // Schema biner

  // Muat ulang menggunakan data biner
  await eval.reloadSchemaMsgpack(schemaMsgpack);
  ```
  ```typescript [Web / NodeJS]
  const schemaMsgpack = new Uint8Array([...]); // Schema biner

  // Muat ulang menggunakan data biner
  await eval.reloadSchemaMsgpack(schemaMsgpack);
  ```
::

## Praktik Terbaik

1.  **Cache Schema Berat**: Selalu gunakan cache untuk schema yang berukuran lebih dari beberapa kilobyte.
2.  **Gunakan Evaluasi Selektif**: Gabungkan caching dengan [Evaluasi Selektif](optimize-selective-evaluation) untuk performa maksimal.
3.  **Gunakan Kembali Instansi**: Di lingkungan stateful (seperti komponen UI), pertahankan instansi `JSONEval` tetap hidup dan gunakan `reload_schema` atau `evaluate` dengan data baru, daripada membuat ulang instansi.
