This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new 97e8157c66 update usage doc (#434)
97e8157c66 is described below
commit 97e8157c66294fffb27989cf0ea066cab13a8dac
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Mar 24 13:25:50 2026 +0800
update usage doc (#434)
---
docs/community/how_to_release.md | 13 +-
docs/introduction/benchmark.md | 77 ++-
docs/start/install.md | 86 ++-
docs/start/usage.md | 374 ++++++++++--
.../current/community/how_to_release.md | 13 +-
.../current/introduction/benchmark.md | 83 ++-
.../current/start/install.md | 118 +++-
.../current/start/usage.md | 673 ++++++++++++++++-----
...ch_deserialize_MEDIA_CONTENT_from_array_tps.png | Bin 33209 -> 104022 bytes
.../bench_deserialize_SAMPLE_from_array_tps.png | Bin 32523 -> 112116 bytes
...ch_deserialize_STRUCT_from_directBuffer_tps.png | Bin 31682 -> 104245 bytes
...ize_compatible_MEDIA_CONTENT_from_array_tps.png | Bin 31840 -> 95479 bytes
...ize_compatible_STRUCT_from_directBuffer_tps.png | Bin 33119 -> 100158 bytes
.../bench_serialize_MEDIA_CONTENT_to_array_tps.png | Bin 33109 -> 102858 bytes
.../bench_serialize_SAMPLE_to_array_tps.png | Bin 32126 -> 120005 bytes
.../bench_serialize_STRUCT_to_directBuffer_tps.png | Bin 32062 -> 117336 bytes
...alize_compatible_MEDIA_CONTENT_to_array_tps.png | Bin 34290 -> 104969 bytes
...alize_compatible_STRUCT_to_directBuffer_tps.png | Bin 34685 -> 115647 bytes
...opy_bench_deserialize_BUFFER_from_array_tps.png | Bin 26864 -> 93509 bytes
...ro_copy_bench_serialize_BUFFER_to_array_tps.png | Bin 25816 -> 94327 bytes
20 files changed, 1153 insertions(+), 284 deletions(-)
diff --git a/docs/community/how_to_release.md b/docs/community/how_to_release.md
index a4abe54c23..767e3e6a8a 100644
--- a/docs/community/how_to_release.md
+++ b/docs/community/how_to_release.md
@@ -208,10 +208,16 @@ If the discussion goes positive, you will need to prepare
the release artifiacts
### Github branch and tag
-- Create a new branch named `releases-0.12.0`
+- Create a new branch named `releases-0.16.0`
- Bump version to `$version` by executing command `python ci/release.py
bump_version -l all -version $version`
- Make a git commit and push the branch to `[email protected]:apache/fory.git`
-- Create a new tag by `git tag v0.12.0-rc1`, then push it to
`[email protected]:apache/fory.git`
+- Create a new release tag by `git tag v0.16.0-rc1`, then push it to
`[email protected]:apache/fory.git`
+- If the Go module under `go/fory` is part of this release, create and push
the Go submodule tag as well. For example, for the final `0.16.0` release:
+
+```bash
+git tag go/fory/v0.16.0
+git push apache go/fory/v0.16.0
+```
### Build and upload artifacts to SVN dist/dev repo
@@ -435,6 +441,9 @@
https://repository.apache.org/content/repositories/orgapachefory-1003
Git tag for the release:
https://github.com/apache/fory/releases/tag/v0.12.0-rc1
+If this release also publishes the Go module, include the Go submodule tag too:
+https://github.com/apache/fory/releases/tag/go/fory/v0.16.0
+
Git commit for the release:
https://github.com/apache/fory/commit/fae06330edd049bb960536e978a45b97bca66faf
diff --git a/docs/introduction/benchmark.md b/docs/introduction/benchmark.md
index 195418881d..2acb2c2d00 100644
--- a/docs/introduction/benchmark.md
+++ b/docs/introduction/benchmark.md
@@ -9,7 +9,14 @@ sidebar_position: 3
## Java Benchmark
-The following benchmarks compare Fory against popular Java serialization
frameworks. Charts labeled **"compatible"** show schema evolution mode with
forward/backward compatibility enabled, while others show schema consistent
mode where class schemas must match.
+The Java benchmark section compares Fory against popular Java serialization
frameworks using the current benchmark suite from `docs/benchmarks/java`.
+
+The plots are grouped by:
+
+- **Heap**: serialization to on-heap `byte[]` buffers
+- **Off-heap**: serialization to direct/off-heap buffers
+- **Compatible**: schema evolution mode with forward/backward compatibility
enabled
+- **Consistent**: schema-consistent mode where peer schemas must match exactly
**Test Classes**:
@@ -17,23 +24,69 @@ The following benchmarks compare Fory against popular Java
serialization framewo
- `MediaContent`: Class from
[jvm-serializers](https://github.com/eishay/jvm-serializers/blob/master/tpc/src/data/media/MediaContent.java)
- `Sample`: Class from [Kryo
benchmark](https://github.com/EsotericSoftware/kryo/blob/master/benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/Sample.java)
-### Java Serialization
+### Heap Serialization
+
+Compatible mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png"
/>
+
+Consistent mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png"
/>
+
+### Off-Heap Serialization
+
+Compatible mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png"
/>
+
+Consistent mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png"
/>
+
+### Heap Deserialization
+
+Compatible mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png"
/>
+
+Consistent mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png"
/>
+
+### Off-Heap Deserialization
+
+Compatible mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png"
/>
+
+Consistent mode:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png"
/>
+
+### Repository Throughput Summary
+
+Serialization throughput:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png" />
+
+Deserialization throughput:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png"
/>
+
+### Zero-Copy Benchmark
+
+Serialize:
-<img width="48%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png" />
+<img width="90%" alt=""
src="/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png"
/>
-### Java Deserialization
+Deserialize:
-<img width="48%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png"
/>
-<img width="48%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png"
/>
+<img width="90%" alt=""
src="/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png"
/>
**Important**: Fory's runtime code generation requires proper warm-up for
performance measurement:
-For additional benchmarks covering type forward/backward compatibility,
off-heap support, and zero-copy serialization, see [Java
Benchmarks](https://github.com/apache/fory/tree/main/docs/benchmarks).
+For additional benchmark notes, raw data, and the complete Java benchmark
README, see [Java
Benchmarks](https://github.com/apache/fory/tree/main/docs/benchmarks/java).
## Rust Benchmark
diff --git a/docs/start/install.md b/docs/start/install.md
index 9f73a9c5d2..efb91da732 100644
--- a/docs/start/install.md
+++ b/docs/start/install.md
@@ -4,13 +4,13 @@ title: Install
sidebar_position: 0
---
-The official Apache Fory™ releases are provided as source artifacts.
+Apache Fory™ releases are available both as source artifacts and
language-specific packages.
-For source download, please see Apache Fory™
[download](https://fory.apache.org/download) page.
+For source downloads, see the Apache Fory™
[download](https://fory.apache.org/download) page.
## Java
-To add a dependency on Apache Fory™ using Maven, use the following:
+Use Maven to add Apache Fory™:
```xml
<dependency>
@@ -23,7 +23,7 @@ To add a dependency on Apache Fory™ using Maven, use the
following:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-format</artifactId>
- <version>0.13.1</version>
+ <version>0.16.0</version>
</dependency>
-->
<!-- SIMD acceleration for array compression (Java 16+) -->
@@ -31,14 +31,14 @@ To add a dependency on Apache Fory™ using Maven, use the
following:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-simd</artifactId>
- <version>0.13.1</version>
+ <version>0.16.0</version>
</dependency>
-->
```
## Scala
-To add a dependency on Apache Fory™ scala for scala 2.13 with maven, use the
following:
+Scala 2.13 with Maven:
```xml
<dependency>
@@ -48,7 +48,7 @@ To add a dependency on Apache Fory™ scala for scala 2.13 with
maven, use the f
</dependency>
```
-To add a dependency on Apache Fory™ scala for scala 3 with maven, use the
following:
+Scala 3 with Maven:
```xml
<dependency>
@@ -58,13 +58,13 @@ To add a dependency on Apache Fory™ scala for scala 3 with
maven, use the foll
</dependency>
```
-To add a dependency on Apache Fory™ scala for scala 2.13 with sbt, use the
following:
+Scala 2.13 with sbt:
```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "0.16.0"
```
-To add a dependency on Apache Fory™ scala for scala 3 with sbt, use the
following:
+Scala 3 with sbt:
```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_3" % "0.16.0"
@@ -72,7 +72,7 @@ libraryDependencies += "org.apache.fory" % "fory-scala_3" %
"0.16.0"
## Kotlin
-To add a dependency on Apache Fory™ kotlin with maven, use the following:
+Add Apache Fory™ Kotlin with Maven:
```xml
<dependency>
@@ -89,14 +89,24 @@ python -m pip install --upgrade pip
pip install pyfory==0.16.0
```
+## Go
+
+Use the full Go module path `github.com/apache/fory/go/fory`:
+
+```bash
+go get github.com/apache/fory/go/[email protected]
+```
+
+If your Go proxy has not picked up the new submodule tag yet, retry later or
use `GOPROXY=direct` temporarily.
+
## Rust
```toml
[dependencies]
-fory = "0.14"
+fory = "0.16.0"
```
-or just execute command:
+Or use `cargo add`:
```bash
cargo add [email protected]
@@ -104,4 +114,54 @@ cargo add [email protected]
## JavaScript
-Apache Fory™ is NOT yet available on npm, please install from source code now.
+The JavaScript packages are defined in the Apache Fory source tree as
`@apache-fory/core` and `@apache-fory/hps`, but they are not published to npm
yet.
+
+Install and build them from source for now:
+
+```bash
+git clone https://github.com/apache/fory.git
+cd fory/javascript
+npm install
+npm run build
+```
+
+After building from source, use `@apache-fory/core` and optionally
`@apache-fory/hps` in your project or workspace setup.
+
+Optional native acceleration requires Node.js 20+:
+
+```bash
+cd packages/hps
+npm run build
+```
+
+## C\#
+
+Install the `Apache.Fory` NuGet package. It includes both the runtime and the
source generator for `[ForyObject]` types.
+
+```bash
+dotnet add package Apache.Fory --version 0.16.0
+```
+
+```xml
+<ItemGroup>
+ <PackageReference Include="Apache.Fory" Version="0.16.0" />
+</ItemGroup>
+```
+
+## Swift
+
+Add Apache Fory™ from the GitHub repository with Swift Package Manager:
+
+```swift
+dependencies: [
+ .package(url: "https://github.com/apache/fory.git", exact: "0.16.0")
+],
+targets: [
+ .target(
+ name: "MyApp",
+ dependencies: [
+ .product(name: "Fory", package: "fory")
+ ]
+ )
+]
+```
diff --git a/docs/start/usage.md b/docs/start/usage.md
index fe52197804..4dc169da0b 100644
--- a/docs/start/usage.md
+++ b/docs/start/usage.md
@@ -10,11 +10,13 @@ This section provides quick examples for getting started
with Apache Fory™.
**Always use native mode when working with a single language.** Native mode
delivers optimal performance by avoiding the type metadata overhead required
for cross-language compatibility.
-Xlang mode introduces additional metadata encoding costs and restricts
serialization to types that are common across all supported languages.
Language-specific types will be rejected during serialization in xlang-mode.
+Xlang mode introduces additional metadata encoding costs and restricts
serialization to types that are common across all supported languages.
Language-specific types will be rejected during serialization in xlang mode.
### Java Serialization
-When you don't need cross-language support, use Java mode for optimal
performance.
+When you do not need cross-language support, use Java mode for optimal
performance.
+
+This example creates a reusable Java-mode runtime, registers a user class, and
then performs a basic serialize/deserialize round trip. In production code,
keep the `Fory` instance alive and reuse it across requests instead of
rebuilding it for every object.
```java
import org.apache.fory.*;
@@ -27,21 +29,21 @@ public class Example {
}
public static void main(String[] args) {
- // Create Fory instance - should be reused across serializations
+ // Create a Fory instance once and reuse it.
BaseFory fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
- // replace `build` with `buildThreadSafeFory` for Thread-Safe Usage
+ // Replace `build` with `buildThreadSafeFory` for thread-safe usage.
.build();
- // Register your classes (required when class registration is enabled)
fory.register(Person.class);
- // Serialize
+
Person person = new Person();
person.name = "chaokunyang";
person.age = 28;
+
byte[] bytes = fory.serialize(person);
Person result = (Person) fory.deserialize(bytes);
- System.out.println(result.name + " " + result.age); // Output:
chaokunyang 28
+ System.out.println(result.name + " " + result.age);
}
}
```
@@ -50,7 +52,9 @@ For detailed Java usage including compatibility modes,
compression, and advanced
### Python Serialization
-Python native mode provides a high-performance drop-in replacement for
pickle/cloudpickle with better speed and compatibility.
+Python native mode provides a high-performance drop-in replacement for
`pickle` and `cloudpickle`.
+
+The example below uses a dataclass with explicit integer typing so Fory can
preserve the intended schema efficiently. As with other runtimes, create the
`Fory` instance once, register your types once, and then reuse it for repeated
serialization.
```python
from dataclasses import dataclass
@@ -61,21 +65,187 @@ class Person:
name: str
age: pyfory.int32
-# Create Fory instance - should be reused across serializations
fory = pyfory.Fory()
-# Register your classes (required when class registration is enabled)
fory.register_type(Person)
+
person = Person(name="chaokunyang", age=28)
data = fory.serialize(person)
result = fory.deserialize(data)
-print(result.name, result.age) # Output: chaokunyang 28
+print(result.name, result.age)
```
For detailed Python usage including type hints, compatibility modes, and
advanced features, see [Python Guide](../guide/python/index.md).
+### Go Serialization
+
+Go native mode is the default. Register your structs once, then reuse the same
`Fory` instance.
+
+The Go runtime works naturally with exported struct fields and explicit type
registration. This snippet shows the standard flow: create `Fory`, register a
struct type, serialize a value, and deserialize into a destination struct.
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/apache/fory/go/fory"
+)
+
+type Person struct {
+ Name string
+ Age int32
+}
+
+func main() {
+ f := fory.New()
+ if err := f.RegisterStruct(Person{}, 1); err != nil {
+ panic(err)
+ }
+
+ person := &Person{Name: "chaokunyang", Age: 28}
+ data, err := f.Serialize(person)
+ if err != nil {
+ panic(err)
+ }
+
+ var result Person
+ if err := f.Deserialize(data, &result); err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("%s %d\n", result.Name, result.Age)
+}
+```
+
+For detailed Go usage including configuration, struct tags, and schema
evolution, see [Go Guide](../guide/go/index.md).
+
+### C# Serialization
+
+C# native serialization uses the `Apache.Fory` runtime together with
`[ForyObject]` model types.
+
+In C#, the usual pattern is to mark your model with `[ForyObject]`, build a
runtime once, and register the type before use. The example demonstrates the
strongly typed `Serialize` and `Deserialize<T>` APIs that fit normal .NET
application code.
+
+```csharp
+using Apache.Fory;
+
+[ForyObject]
+public sealed class Person
+{
+ public string Name { get; set; } = string.Empty;
+ public int Age { get; set; }
+}
+
+Fory fory = Fory.Builder().Build();
+fory.Register<Person>(1);
+
+Person person = new() { Name = "chaokunyang", Age = 28 };
+byte[] data = fory.Serialize(person);
+Person result = fory.Deserialize<Person>(data);
+
+Console.WriteLine($"{result.Name} {result.Age}");
+```
+
+For detailed C# usage including source generators, references, and schema
evolution, see [C# Guide](../guide/csharp/index.md).
+
+### Swift Serialization
+
+Swift native serialization uses `@ForyObject` models and the `Fory` runtime
directly.
+
+Swift uses macro-based model definitions, so the example starts by annotating
the type with `@ForyObject`, then registers the type ID and performs a typed
round trip. This is the recommended starting point for app-side Swift usage.
+
+```swift
+import Fory
+
+@ForyObject
+struct Person: Equatable {
+ var name: String = ""
+ var age: Int32 = 0
+}
+
+let fory = Fory()
+fory.register(Person.self, id: 1)
+
+let person = Person(name: "chaokunyang", age: 28)
+let data = try fory.serialize(person)
+let result: Person = try fory.deserialize(data)
+
+print("\(result.name) \(result.age)")
+```
+
+For detailed Swift usage including polymorphism, schema evolution, and
troubleshooting, see [Swift Guide](../guide/swift/index.md).
+
+### Rust Serialization
+
+Rust native mode uses `Fory::default()` and derive macros for compile-time
type-safe serialization. The normal pattern is to derive `ForyObject`, register
the type once, and then reuse the configured runtime for repeated serialization.
+
+```rust
+use fory::{Error, Fory, ForyObject};
+
+#[derive(ForyObject, Debug, PartialEq)]
+struct Person {
+ name: String,
+ age: i32,
+}
+
+fn main() -> Result<(), Error> {
+ let mut fory = Fory::default();
+ fory.register::<Person>(1)?;
+
+ let person = Person {
+ name: "chaokunyang".to_string(),
+ age: 28,
+ };
+
+ let bytes = fory.serialize(&person)?;
+ let result: Person = fory.deserialize(&bytes)?;
+ assert_eq!(person, result);
+ Ok(())
+}
+```
+
+For detailed Rust usage including references, polymorphism, and row format
support, see [Rust Guide](../guide/rust/index.md).
+
+### C++ Serialization
+
+C++ native mode uses the `FORY_STRUCT` macro to describe serializable fields
and a configured `Fory` runtime to encode and decode values. For
single-language C++ usage, set `xlang(false)` explicitly so the runtime stays
in native mode.
+
+```cpp
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+struct Person {
+ std::string name;
+ int32_t age;
+
+ bool operator==(const Person &other) const {
+ return name == other.name && age == other.age;
+ }
+
+ FORY_STRUCT(Person, name, age);
+};
+
+int main() {
+ auto fory = Fory::builder().xlang(false).build();
+ fory.register_struct<Person>(1);
+
+ Person person{"chaokunyang", 28};
+
+ auto bytes = fory.serialize(person);
+ auto result = fory.deserialize<Person>(bytes.value());
+ assert(result.ok());
+ assert(person == result.value());
+ return 0;
+}
+```
+
+For detailed C++ usage including `FORY_STRUCT`, thread safety, and schema
evolution, see [C++ Guide](../guide/cpp/index.md).
+
### Scala Serialization
-Scala native mode provides optimized serialization for Scala-specific types
including case classes, collections, and Option types.
+Scala native mode provides optimized serialization for Scala-specific types
including case classes, collections, and `Option`.
+
+For Scala projects, register the Scala serializers first so Fory understands
Scala-specific data structures correctly. After that, you can register your
case classes and use the same core API as the Java runtime.
```scala
import org.apache.fory.Fory
@@ -86,18 +256,16 @@ case class Person(name: String, age: Int)
object Example {
def main(args: Array[String]): Unit = {
- // Create Fory instance - should be reused across serializations
val fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
.build()
- // Register Scala serializers for Scala-specific types
ScalaSerializers.registerSerializers(fory)
- // Register your case classes
fory.register(classOf[Person])
+
val bytes = fory.serialize(Person("chaokunyang", 28))
val result = fory.deserialize(bytes).asInstanceOf[Person]
- println(s"${result.name} ${result.age}") // Output: chaokunyang 28
+ println(s"${result.name} ${result.age}")
}
}
```
@@ -108,6 +276,8 @@ For detailed Scala usage including collection serialization
and integration patt
Kotlin native mode provides optimized serialization for Kotlin-specific types
including data classes, nullable types, and Kotlin collections.
+Kotlin follows the same builder flow as Java, with an extra registration step
for Kotlin-specific serializers. The example uses a data class and shows the
minimal setup needed for efficient native serialization.
+
```kotlin
import org.apache.fory.Fory
import org.apache.fory.config.Language
@@ -116,18 +286,16 @@ import org.apache.fory.serializer.kotlin.KotlinSerializers
data class Person(val name: String, val age: Int)
fun main() {
- // Create Fory instance - should be reused across serializations
val fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
.build()
- // Register Kotlin serializers for Kotlin-specific types
KotlinSerializers.registerSerializers(fory)
- // Register your data classes
fory.register(Person::class.java)
+
val bytes = fory.serialize(Person("chaokunyang", 28))
val result = fory.deserialize(bytes) as Person
- println("${result.name} ${result.age}") // Output: chaokunyang 28
+ println("${result.name} ${result.age}")
}
```
@@ -135,12 +303,14 @@ For detailed Kotlin usage including null safety and
default value support, see [
## Cross-Language Serialization
-**Only use xlang mode when you need cross-language data exchange.** Xlang mode
adds type metadata overhead for cross-language compatibility and only supports
types that can be mapped across all languages. For single-language use cases,
always prefer native mode for better performance.
+**Only use xlang mode when you need cross-language data exchange.** Xlang mode
adds type metadata overhead for cross-language compatibility and only supports
types that can be mapped across all languages.
-The following examples demonstrate serializing a `Person` object across Java
and Rust. For other languages (Python, Go, JavaScript, etc.), simply set the
language mode to `XLANG` and follow the same pattern.
+The examples below use the same `Person` schema across multiple runtimes. In
every language, enable xlang mode and register the type with the same ID or the
same fully qualified name.
### Java
+Java xlang usage is the baseline pattern for JVM services. Enable
`Language.XLANG`, register the type with a stable ID or name, and make sure
every peer language uses the same mapping.
+
```java
import org.apache.fory.*;
import org.apache.fory.config.*;
@@ -149,27 +319,67 @@ public class XlangExample {
public record Person(String name, int age) {}
public static void main(String[] args) {
- // Create Fory instance with XLANG mode
Fory fory = Fory.builder()
.withLanguage(Language.XLANG)
.build();
- // Register with cross-language type id/name
fory.register(Person.class, 1);
// fory.register(Person.class, "example.Person");
+
Person person = new Person("chaokunyang", 28);
byte[] bytes = fory.serialize(person);
- // bytes can be deserialized by Rust, Python, Go, or other languages
Person result = (Person) fory.deserialize(bytes);
- System.out.println(result.name + " " + result.age); // Output:
chaokunyang 28
+ System.out.println(result.name() + " " + result.age());
}
}
```
+### Go
+
+Go xlang mode is enabled through `WithXlang(true)`. The important part is not
the Go syntax itself, but keeping the registered type identity aligned with
every other language that reads or writes the payload.
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/apache/fory/go/fory"
+)
+
+type Person struct {
+ Name string
+ Age int32
+}
+
+func main() {
+ f := fory.New(fory.WithXlang(true))
+ if err := f.RegisterStruct(Person{}, 1); err != nil {
+ panic(err)
+ }
+
+ person := &Person{Name: "chaokunyang", Age: 28}
+ data, err := f.Serialize(person)
+ if err != nil {
+ panic(err)
+ }
+
+ var result Person
+ if err := f.Deserialize(data, &result); err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("%s %d\n", result.Name, result.Age)
+}
+```
+
### Rust
+Rust follows the same cross-language contract, but expresses it through
derived traits and explicit registration on the `Fory` instance. Once the type
ID matches the other runtimes, the payload can move across language boundaries
safely.
+
```rust
use fory::{Fory, ForyObject};
+use std::error::Error;
#[derive(ForyObject, Debug)]
struct Person {
@@ -177,74 +387,116 @@ struct Person {
age: i32,
}
-fn main() -> Result<(), Error> {
- let mut fory = Fory::default();
+fn main() -> Result<(), Box<dyn Error>> {
+ let mut fory = Fory::default().xlang(true);
fory.register::<Person>(1)?;
// fory.register_by_name::<Person>("example.Person")?;
+
let person = Person {
name: "chaokunyang".to_string(),
age: 28,
};
let bytes = fory.serialize(&person);
- // bytes can be deserialized by Java, Python, Go, or other languages
let result: Person = fory.deserialize(&bytes)?;
- println!("{} {}", result.name, result.age); // Output: chaokunyang 28
+ println!("{} {}", result.name, result.age);
+ Ok(())
}
```
-### Golang
+### JavaScript
-```go
-type Person struct {
- name: string
- age: i32
-}
-fory := fory.NewFory(true)
-fory.Register(Person{}, 1)
-person := Person{"chaokunyang", 28}
-bytes, err := fory.Marshal(person)
-var p Person
-err = fory.Unmarshal(bytes, &p)
-```
+JavaScript cross-language support is schema-driven. Instead of registering a
class, you describe the payload shape with `Type.object(...)`, then use the
returned serializer pair to encode and decode values.
-### JavaScript
+These packages are not published to npm yet. Build them from the Apache Fory
repository first, then use the following API shape.
```javascript
-import Fory, { Type } from "@apache-fory/fory";
+import Fory, { Type } from "@apache-fory/core";
/**
- * @apache-fory/hps use v8's fast-calls-api that can be called directly by
jit, ensure that the version of Node is 20 or above.
- * Experimental feature, installation success cannot be guaranteed at this
moment
- * If you are unable to install the module, replace it with `const hps = null;`
- **/
+ * `@apache-fory/hps` uses V8 fast calls directly from JIT.
+ * Use Node.js 20+ when enabling it.
+ * If installation fails, replace it with `const hps = null;`.
+ */
import hps from "@apache-fory/hps";
-// Now we describe data structures using JSON, but in the future, we will use
more ways.
const description = Type.object("example.Person", {
name: Type.string(),
age: Type.int32(),
});
+
const fory = new Fory({ hps });
const { serialize, deserialize } = fory.registerSerializer(description);
-const input = serialize({ name: "chaokunyang", age: 28 });
-const result = deserialize(input);
+
+const payload = serialize({ name: "chaokunyang", age: 28 });
+const result = deserialize(payload);
console.log(result);
```
+### C\#
+
+C# cross-language code looks similar to native usage, but the runtime is
explicitly configured for xlang and compatible mode. Use the same type ID or
namespace/name mapping as your Java, Go, Swift, or Rust peers.
+
+```csharp
+using Apache.Fory;
+
+[ForyObject]
+public sealed class Person
+{
+ public string Name { get; set; } = string.Empty;
+ public int Age { get; set; }
+}
+
+Fory fory = Fory.Builder()
+ .Xlang(true)
+ .Compatible(true)
+ .Build();
+
+fory.Register<Person>(1);
+
+Person person = new() { Name = "chaokunyang", Age = 28 };
+byte[] payload = fory.Serialize(person);
+Person result = fory.Deserialize<Person>(payload);
+
+Console.WriteLine($"{result.Name} {result.Age}");
+```
+
+### Swift
+
+Swift cross-language serialization uses the same `@ForyObject` model style as
native mode, but you create the runtime with `xlang: true`. Stable registration
IDs are still the key requirement for interoperability.
+
+```swift
+import Fory
+
+@ForyObject
+struct Person: Equatable {
+ var name: String = ""
+ var age: Int32 = 0
+}
+
+let fory = Fory(xlang: true, trackRef: false, compatible: true)
+fory.register(Person.self, id: 1)
+
+let person = Person(name: "chaokunyang", age: 28)
+let data = try fory.serialize(person)
+let result: Person = try fory.deserialize(data)
+
+print("\(result.name) \(result.age)")
+```
+
### Key Points
-- Use `Language.XLANG` mode in all languages
-- Register types with **consistent IDs or names** across all languages:
- - **By ID** (`fory.register(Person.class, 1)`): Faster serialization, more
compact encoding, but requires coordination to avoid ID conflicts
- - **By name** (`fory.register(Person.class, "example.Person")`): More
flexible, less prone to conflicts, easier to manage across teams, but slightly
larger encoding
-- Type IDs/names must match across all languages for successful deserialization
-- Only use types that have cross-language mappings (see [Type
Mapping](../specification/xlang_type_mapping.md))
+- Enable xlang mode in every runtime (`Language.XLANG`, `WithXlang(true)`,
`Xlang(true)`, `Fory(xlang: true, ...)`, and so on).
+- Register types with **consistent IDs or names** across all languages.
+- ID-based registration is more compact and faster, but it requires
coordination to avoid conflicts.
+- Name-based registration is easier to manage across teams, but it produces
slightly larger payloads.
+- Only use types that have cross-language mappings; see [Type
Mapping](../specification/xlang_type_mapping.md).
-For examples with **circular references**, **shared references**, and
**polymorphism** across languages, see:
+For examples with circular references, shared references, and polymorphism
across languages, see:
- [Cross-Language Serialization Guide](../guide/xlang/index.md)
-- [Java Serialization Guide - Cross Language](../guide/java/cross-language.md)
-- [Python Guide - Cross Language](../guide/python/cross-language.md)
+- [Go Guide - Cross Language](../guide/go/cross-language.md)
+- [C# Guide - Cross Language](../guide/csharp/cross-language.md)
+- [Swift Guide - Cross Language](../guide/swift/cross-language.md)
## Row Format Encoding
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/community/how_to_release.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/community/how_to_release.md
index acd0f0b1c8..5813567f39 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/community/how_to_release.md
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/community/how_to_release.md
@@ -202,10 +202,16 @@ ${name}
### Github 分支和标签
-- 创建一个名为 `releases-0.12.0`
+- 创建一个名为 `releases-0.16.0`
- 通过执行命令将版本 `$version` 升级到 `python ci/release.py bump_version -l all -version
$version`
- 执行 git commit 并将分支推送到 `[email protected]:apache/fory.git`
-- 通过 `git tag v0.12.0-rc1` 创建一个新标签,然后将其推送到 `[email protected]:apache/fory.git`
+- 通过 `git tag v0.16.0-rc1` 创建一个 release 标签,然后将其推送到
`[email protected]:apache/fory.git`
+- 如果本次发布包含 `go/fory` 这个 Go 子模块,还需要额外创建并推送 Go 子模块标签。例如,对于最终版 `0.16.0`,执行:
+
+```bash
+git tag go/fory/v0.16.0
+git push apache go/fory/v0.16.0
+```
### 构建 artifacts 并上传到 SVN dist/dev 仓库
@@ -284,6 +290,9 @@
https://repository.apache.org/content/repositories/orgapachefory-1003
Git tag for the release:
https://github.com/apache/fory/releases/tag/v0.12.0-rc1
+如果本次发布还包含 Go 模块,请同时附上 Go 子模块标签:
+https://github.com/apache/fory/releases/tag/go/fory/v0.16.0
+
Git commit for the release:
https://github.com/apache/fory/commit/fae06330edd049bb960536e978a45b97bca66faf
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/introduction/benchmark.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/introduction/benchmark.md
index dd2e7d353b..568bd14fc0 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/introduction/benchmark.md
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/introduction/benchmark.md
@@ -13,21 +13,82 @@ sidebar_position: 2
## Java 性能测试
-### Java 序列化
+Java 部分已切换为 `docs/benchmarks/java` 中的最新性能测试图。图表现在按以下维度分组:
-<img width="33%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png" />
+- **Heap**:序列化到堆上 `byte[]` 缓冲区
+- **Off-heap**:序列化到 direct/off-heap 缓冲区
+- **Compatible**:启用前向/后向兼容的 Schema 演进模式
+- **Consistent**:要求读写两端 Schema 完全一致的模式
-### Java 反序列化
+**测试数据类型**:
-<img width="33%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png"
/>
-<img width="33%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png"
/>
+- `Struct`:包含 [100
个基础类型字段](https://github.com/apache/fory/tree/main/docs/benchmarks#Struct) 的类
+- `MediaContent`:来自
[jvm-serializers](https://github.com/eishay/jvm-serializers/blob/master/tpc/src/data/media/MediaContent.java)
的类
+- `Sample`:来自 [Kryo
benchmark](https://github.com/EsotericSoftware/kryo/blob/master/benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/Sample.java)
的类
-更多关于类型前向/后向兼容性、堆外支持、零拷贝序列化的性能测试,请参见
[benchmarks](https://github.com/apache/fory/tree/main/docs/benchmarks)。
+### Heap 序列化
+
+Compatible 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png"
/>
+
+Consistent 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png"
/>
+
+### Off-heap 序列化
+
+Compatible 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png"
/>
+
+Consistent 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png"
/>
+
+### Heap 反序列化
+
+Compatible 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png"
/>
+
+Consistent 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png"
/>
+
+### Off-heap 反序列化
+
+Compatible 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png"
/>
+
+Consistent 模式:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png"
/>
+
+### 仓库基准汇总
+
+序列化吞吐:
+
+<img width="90%" alt=""
src="/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png" />
+
+反序列化吞吐:
+
+<img width="90%" alt=""
src="/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png"
/>
+
+### 零拷贝性能测试
+
+序列化:
+
+<img width="90%" alt=""
src="/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png"
/>
+
+反序列化:
+
+<img width="90%" alt=""
src="/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png"
/>
+
+注意:Apache Fory™ 依赖运行时代码生成,进行性能测试前必须充分预热。
+
+更多说明、原始数据和完整 Java benchmark README 请参见 [Java
Benchmarks](https://github.com/apache/fory/tree/main/docs/benchmarks/java)。
## Rust 性能测试
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md
index 9b6077dc6e..ecb8b83e43 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md
@@ -4,98 +4,164 @@ title: 安装 Apache Fory™
sidebar_position: 0
---
-Apache Fory™ 源码下载请参见 Apache Fory™
[download](https://github.com/apache/fory/releases)页面。
+Apache Fory™ 同时提供源码发布物和各语言对应的软件包。
-## 安装 Apache Fory™ Java
+源码下载请参见 Apache Fory™ [download](https://fory.apache.org/download) 页面。
-要使用 Maven 添加对 Apache Fory™ 的依赖,请使用以下配置:
+## Java
+
+使用 Maven 添加 Apache Fory™:
```xml
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-core</artifactId>
- <version>0.14.1</version>
+ <version>0.16.0</version>
</dependency>
-<!-- Optional row format support -->
+<!-- 可选:row format 支持 -->
<!--
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-format</artifactId>
- <version>0.13.1</version>
+ <version>0.16.0</version>
</dependency>
-->
-<!-- SIMD acceleration for array compression (Java 16+) -->
+<!-- 可选:数组压缩 SIMD 加速(Java 16+) -->
<!--
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-simd</artifactId>
- <version>0.13.1</version>
+ <version>0.16.0</version>
</dependency>
-->
```
-## 安装 Apache Fory™ Scala
+## Scala
-要使用 Maven 添加 scala 2.13 的 Fory scala 依赖,请使用以下配置:
+Scala 2.13 的 Maven 依赖:
```xml
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-scala_2.13</artifactId>
- <version>0.14.1</version>
+ <version>0.16.0</version>
</dependency>
```
-要使用 Maven 添加 scala 3 的 Fory scala 依赖,请使用以下配置:
+Scala 3 的 Maven 依赖:
```xml
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-scala_3</artifactId>
- <version>0.14.1</version>
+ <version>0.16.0</version>
</dependency>
```
-要使用 sbt 添加 scala 2.13 的 Fory scala 依赖,请使用以下配置:
+Scala 2.13 的 sbt 依赖:
```sbt
-libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "0.14.1"
+libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "0.16.0"
```
-要使用 sbt 添加 scala 3 的 Fory scala 依赖,请使用以下配置:
+Scala 3 的 sbt 依赖:
```sbt
-libraryDependencies += "org.apache.fory" % "fory-scala_3" % "0.14.1"
+libraryDependencies += "org.apache.fory" % "fory-scala_3" % "0.16.0"
```
-## 安装 Apache Fory™ Kotlin
+## Kotlin
-To add a dependency on Apache Fory™kotlin with maven, use the following:
+使用 Maven 添加 Apache Fory™ Kotlin:
```xml
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-kotlin</artifactId>
- <version>0.14.1</version>
+ <version>0.16.0</version>
</dependency>
```
-## 安装 Apache Fory™ Python
+## Python
```bash
python -m pip install --upgrade pip
-pip install pyfory==0.14.1
+pip install pyfory==0.16.0
```
-## 安装 Apache Fory™ Rust
+## Go
+
+请使用完整的 Go 模块路径 `github.com/apache/fory/go/fory`:
+
+```bash
+go get github.com/apache/fory/go/[email protected]
+```
+
+如果你的 Go proxy 还没有同步到新的子模块 tag,可以稍后重试,或者临时使用 `GOPROXY=direct`。
+
+## Rust
```toml
[dependencies]
-fory = "0.14"
+fory = "0.16.0"
+```
+
+或者使用 `cargo add`:
+
+```bash
+cargo add [email protected]
+```
+
+## JavaScript
+
+Apache Fory 的 JavaScript 包在源码仓库中定义为 `@apache-fory/core` 和
`@apache-fory/hps`,但目前还没有发布到 npm。
+
+目前请先从源码安装并构建:
+
+```bash
+git clone https://github.com/apache/fory.git
+cd fory/javascript
+npm install
+npm run build
+```
+
+完成源码构建后,再在你的项目或 workspace 中使用 `@apache-fory/core`,并按需启用 `@apache-fory/hps`。
+
+可选的原生加速模块需要 Node.js 20+:
+
+```bash
+cd packages/hps
+npm run build
```
-或者直接执行以下命令:
+## C\#
+
+安装 `Apache.Fory` NuGet 包。它同时包含运行时和 `[ForyObject]` 类型所需的源代码生成器。
```bash
-cargo add [email protected]
+dotnet add package Apache.Fory --version 0.16.0
+```
+
+```xml
+<ItemGroup>
+ <PackageReference Include="Apache.Fory" Version="0.16.0" />
+</ItemGroup>
+```
+
+## Swift
+
+使用 Swift Package Manager 从 GitHub 仓库引入 Apache Fory™:
+
+```swift
+dependencies: [
+ .package(url: "https://github.com/apache/fory.git", exact: "0.16.0")
+],
+targets: [
+ .target(
+ name: "MyApp",
+ dependencies: [
+ .product(name: "Fory", package: "fory")
+ ]
+ )
+]
```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/usage.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/usage.md
index bd9ce3a1b3..f1a27c31db 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/usage.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/usage.md
@@ -4,233 +4,592 @@ title: Apache Fory™ 使用
sidebar_position: 1
---
-本章节演示不同编程语言使用 Apache Fory™ 进行序列化。
+本章节提供 Apache Fory™ 的快速入门示例。
-## Java 序列化
+## 原生序列化
+
+**当你只在单一语言内使用时,请始终选择原生模式。** 原生模式不需要为跨语言兼容写入额外类型元信息,因此性能最好。
+
+xlang 模式会引入额外的元信息编码开销,并且只允许序列化所有受支持语言都能映射的类型。语言特有类型在 xlang 模式下会被拒绝。
+
+### Java 序列化
+
+如果不需要跨语言支持,请使用 Java 模式以获得最佳性能。
+
+下面的示例展示了最基本的 Java 原生用法:创建可复用的 Java
模式运行时、注册用户类型,然后完成一次序列化和反序列化往返。实际项目中不要为每个对象重新创建 `Fory` 实例,而应长期复用同一个实例。
```java
-import java.util.List;
-import java.util.Arrays;
-import io.fory.*;
+import org.apache.fory.*;
+import org.apache.fory.config.*;
public class Example {
+ public static class Person {
+ String name;
+ int age;
+ }
+
public static void main(String[] args) {
- SomeClass object = new SomeClass();
- // Note that Fory instances should be reused between
- // multiple serializations of different objects.
- Fory fory = Fory.builder().withLanguage(Language.JAVA)
- // Allow to deserialize objects unknown types,
- // more flexible but less secure.
- // .requireClassRegistration(false)
+ // 创建一次 Fory 实例并重复复用。
+ BaseFory fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ // 如果需要线程安全用法,请将 `build` 替换为 `buildThreadSafeFory`。
.build();
- // Registering types can reduce class name serialization overhead, but not
mandatory.
- // If secure mode enabled, all custom types must be registered.
- fory.register(SomeClass.class);
- byte[] bytes = fory.serialize(object);
- System.out.println(fory.deserialize(bytes));
+ fory.register(Person.class);
+
+ Person person = new Person();
+ person.name = "chaokunyang";
+ person.age = 28;
+
+ byte[] bytes = fory.serialize(person);
+ Person result = (Person) fory.deserialize(bytes);
+ System.out.println(result.name + " " + result.age);
}
}
```
-## Scala序列化
+关于兼容模式、压缩和更多高级特性,请参见 [Java 序列化指南](../guide/java/index.md)。
+
+### Python 序列化
+
+Python 原生模式可以作为 `pickle` 和 `cloudpickle` 的高性能替代方案。
+
+这个示例使用 dataclass 和显式整数类型注解,让 Fory 能以更清晰的 Schema 进行高效序列化。与其他语言一样,推荐只创建一次 `Fory`
实例、只注册一次类型,然后在后续调用中重复使用。
+
+```python
+from dataclasses import dataclass
+import pyfory
+
+@dataclass
+class Person:
+ name: str
+ age: pyfory.int32
+
+fory = pyfory.Fory()
+fory.register_type(Person)
+
+person = Person(name="chaokunyang", age=28)
+data = fory.serialize(person)
+result = fory.deserialize(data)
+print(result.name, result.age)
+```
+
+关于类型注解、兼容模式和更多高级特性,请参见 [Python 指南](../guide/python/index.md)。
+
+### Go 序列化
+
+Go 原生模式默认启用。注册一次结构体后,重复复用同一个 `Fory` 实例即可。
+
+Go 运行时天然适配导出的 struct 字段和显式类型注册。下面的代码演示了最常见的流程:创建
`Fory`、注册结构体类型、序列化一个值,再反序列化到目标结构体中。
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/apache/fory/go/fory"
+)
+
+type Person struct {
+ Name string
+ Age int32
+}
+
+func main() {
+ f := fory.New()
+ if err := f.RegisterStruct(Person{}, 1); err != nil {
+ panic(err)
+ }
+
+ person := &Person{Name: "chaokunyang", Age: 28}
+ data, err := f.Serialize(person)
+ if err != nil {
+ panic(err)
+ }
+
+ var result Person
+ if err := f.Deserialize(data, &result); err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("%s %d\n", result.Name, result.Age)
+}
+```
+
+关于配置、struct tag 和 Schema 演进,请参见 [Go 指南](../guide/go/index.md)。
+
+### C# 序列化
+
+C# 原生序列化使用 `Apache.Fory` 运行时和 `[ForyObject]` 模型类型。
+
+在 C# 中,常见模式是先用 `[ForyObject]` 标记模型,再创建一次运行时并在使用前注册类型。示例展示的是强类型的 `Serialize` /
`Deserialize<T>` API,这也是 .NET 应用中最直接的用法。
+
+```csharp
+using Apache.Fory;
+
+[ForyObject]
+public sealed class Person
+{
+ public string Name { get; set; } = string.Empty;
+ public int Age { get; set; }
+}
+
+Fory fory = Fory.Builder().Build();
+fory.Register<Person>(1);
+
+Person person = new() { Name = "chaokunyang", Age = 28 };
+byte[] data = fory.Serialize(person);
+Person result = fory.Deserialize<Person>(data);
+
+Console.WriteLine($"{result.Name} {result.Age}");
+```
-````scala
+关于源代码生成器、引用跟踪和 Schema 演进,请参见 [C# 指南](../guide/csharp/index.md)。
+
+### Swift 序列化
+
+Swift 原生序列化直接使用 `@ForyObject` 模型和 `Fory` 运行时。
+
+Swift 通过宏定义模型类型,因此示例先使用 `@ForyObject` 标记类型,再注册类型 ID 并完成一次强类型往返。这是 Swift
应用侧最推荐的入门方式。
+
+```swift
+import Fory
+
+@ForyObject
+struct Person: Equatable {
+ var name: String = ""
+ var age: Int32 = 0
+}
+
+let fory = Fory()
+fory.register(Person.self, id: 1)
+
+let person = Person(name: "chaokunyang", age: 28)
+let data = try fory.serialize(person)
+let result: Person = try fory.deserialize(data)
+
+print("\(result.name) \(result.age)")
+```
+
+关于多态、Schema 演进和常见问题排查,请参见 [Swift 指南](../guide/swift/index.md)。
+
+### Rust 序列化
+
+Rust 原生模式使用 `Fory::default()` 和 derive 宏来实现编译期类型安全的序列化。常见模式是先为类型派生
`ForyObject`,注册一次类型,再重复复用已经配置好的运行时。
+
+```rust
+use fory::{Error, Fory, ForyObject};
+
+#[derive(ForyObject, Debug, PartialEq)]
+struct Person {
+ name: String,
+ age: i32,
+}
+
+fn main() -> Result<(), Error> {
+ let mut fory = Fory::default();
+ fory.register::<Person>(1)?;
+
+ let person = Person {
+ name: "chaokunyang".to_string(),
+ age: 28,
+ };
+
+ let bytes = fory.serialize(&person)?;
+ let result: Person = fory.deserialize(&bytes)?;
+ assert_eq!(person, result);
+ Ok(())
+}
+```
+
+关于引用、多态和 row format 支持,请参见 [Rust 指南](../guide/rust/index.md)。
+
+### C++ 序列化
+
+C++ 原生模式使用 `FORY_STRUCT` 宏描述可序列化字段,再通过配置好的 `Fory` 运行时对值进行编码和解码。对于单语言 C++
场景,建议显式设置 `xlang(false)`,让运行时保持在原生模式。
+
+```cpp
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+struct Person {
+ std::string name;
+ int32_t age;
+
+ bool operator==(const Person &other) const {
+ return name == other.name && age == other.age;
+ }
+
+ FORY_STRUCT(Person, name, age);
+};
+
+int main() {
+ auto fory = Fory::builder().xlang(false).build();
+ fory.register_struct<Person>(1);
+
+ Person person{"chaokunyang", 28};
+
+ auto bytes = fory.serialize(person);
+ auto result = fory.deserialize<Person>(bytes.value());
+ assert(result.ok());
+ assert(person == result.value());
+ return 0;
+}
+```
+
+关于 `FORY_STRUCT`、线程安全和 Schema 演进,请参见 [C++ 指南](../guide/cpp/index.md)。
+
+### Scala 序列化
+
+Scala 原生模式对 case class、集合和 `Option` 等 Scala 特有类型提供了优化支持。
+
+在 Scala 项目中,应先注册 Scala 专用序列化器,让 Fory 正确理解 Scala 特有的数据结构。完成这一步后,就可以像 Java
运行时一样注册 case class 并执行序列化。
+
+```scala
import org.apache.fory.Fory
+import org.apache.fory.config.Language
import org.apache.fory.serializer.scala.ScalaSerializers
-case class Person(name: String, id: Long, github: String)
-case class Point(x : Int, y : Int, z : Int)
-
-object ScalaExample {
- val fory: Fory = Fory.builder().withScalaOptimizationEnabled(true).build()
- // Register optimized fory serializers for scala
- ScalaSerializers.registerSerializers(fory)
- fory.register(classOf[Person])
- fory.register(classOf[Point])
+case class Person(name: String, age: Int)
+object Example {
def main(args: Array[String]): Unit = {
- val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
- println(fory.deserialize(fory.serialize(p)))
- println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
+ val fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
+ ScalaSerializers.registerSerializers(fory)
+ fory.register(classOf[Person])
+
+ val bytes = fory.serialize(Person("chaokunyang", 28))
+ val result = fory.deserialize(bytes).asInstanceOf[Person]
+ println(s"${result.name} ${result.age}")
}
}
+```
+
+关于集合序列化和集成模式,请参见 [Scala 指南](../guide/scala/index.md)。
+
+### Kotlin 序列化
+
+Kotlin 原生模式对 data class、可空类型和 Kotlin 集合提供了优化支持。
+
+Kotlin 的整体流程与 Java 类似,只是额外需要注册 Kotlin 专用序列化器。下面的示例使用 data
class,展示了进行高效原生序列化所需的最小配置。
-## Kotlin序列化
```kotlin
import org.apache.fory.Fory
-import org.apache.fory.ThreadSafeFory
+import org.apache.fory.config.Language
import org.apache.fory.serializer.kotlin.KotlinSerializers
-data class Person(val name: String, val id: Long, val github: String)
-data class Point(val x : Int, val y : Int, val z : Int)
+data class Person(val name: String, val age: Int)
-fun main(args: Array<String>) {
- // 注意: 下面的Fory初始化代码应该只执行一次,而不是在每次序列化前都运行
- val fory: ThreadSafeFory =
Fory.builder().requireClassRegistration(true).buildThreadSafeFory()
+fun main() {
+ val fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
KotlinSerializers.registerSerializers(fory)
fory.register(Person::class.java)
- fory.register(Point::class.java)
- val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
- println(fory.deserialize(fory.serialize(p)))
- println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
+ val bytes = fory.serialize(Person("chaokunyang", 28))
+ val result = fory.deserialize(bytes) as Person
+ println("${result.name} ${result.age}")
}
-````
+```
+
+关于空安全和默认值支持,请参见
[kotlin/README.md](https://github.com/apache/fory/blob/main/kotlin/README.md)。
## 跨语言序列化
+**只有在确实需要跨语言数据交换时才使用 xlang 模式。** xlang 模式会为跨语言兼容增加类型元信息开销,并且只支持能够在所有语言之间映射的类型。
+
+下面的示例在多个运行时中使用同一个 `Person` Schema。无论使用哪种语言,都需要启用 xlang 模式,并用相同的 ID
或相同的全限定名称注册类型。
+
### Java
+Java 的 xlang 用法可以看作 JVM 服务中的基准模式。启用 `Language.XLANG` 后,用稳定的 ID
或名称注册类型,并确保所有对端语言都使用相同的映射关系。
+
```java
-import com.google.common.collect.ImmutableMap;
-import io.fory.*;
+import org.apache.fory.*;
+import org.apache.fory.config.*;
-import java.util.Map;
+public class XlangExample {
+ public record Person(String name, int age) {}
-public class ReferenceExample {
- public static class SomeClass {
- SomeClass f1;
- Map<String, String> f2;
- Map<String, String> f3;
- }
+ public static void main(String[] args) {
+ Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .build();
- public static Object createObject() {
- SomeClass obj = new SomeClass();
- obj.f1 = obj;
- obj.f2 = ImmutableMap.of("k1", "v1", "k2", "v2");
- obj.f3 = obj.f2;
- return obj;
- }
+ fory.register(Person.class, 1);
+ // fory.register(Person.class, "example.Person");
- // mvn exec:java -Dexec.mainClass="io.fory.examples.ReferenceExample"
- public static void main(String[] args) {
- Fory fory = Fory.builder().withLanguage(Language.XLANG)
- .withRefTracking(true).build();
- fory.register(SomeClass.class, "example.SomeClass");
- byte[] bytes = fory.serialize(createObject());
- // bytes can be data serialized by other languages.
- System.out.println(fory.deserialize(bytes));
- ;
+ Person person = new Person("chaokunyang", 28);
+ byte[] bytes = fory.serialize(person);
+ Person result = (Person) fory.deserialize(bytes);
+ System.out.println(result.name() + " " + result.age());
}
}
```
-### Python
-
-```python
-from typing import Dict
-import pyfory
-
-class SomeClass:
- f1: "SomeClass"
- f2: Dict[str, str]
- f3: Dict[str, str]
-
-fory = pyfory.Fory(ref_tracking=True)
-fory.register_class(SomeClass, "example.SomeClass")
-obj = SomeClass()
-obj.f2 = {"k1": "v1", "k2": "v2"}
-obj.f1, obj.f3 = obj, obj.f2
-data = fory.serialize(obj)
-# bytes can be data serialized by other languages.
-print(fory.deserialize(data))
-```
+### Go
-### Golangs
+Go 通过 `WithXlang(true)` 启用跨语言模式。真正关键的不是 Go 语法本身,而是保证注册的类型身份与其他读写同一载荷的语言完全一致。
```go
package main
import (
- "fmt"
- forygo "github.com/apache/fory/go/fory"
+ "fmt"
+
+ "github.com/apache/fory/go/fory"
)
+type Person struct {
+ Name string
+ Age int32
+}
+
func main() {
- type SomeClass struct {
- F1 *SomeClass
- F2 map[string]string
- F3 map[string]string
- }
- fory := forygo.NewFory(true)
- if err := fory.RegisterTagType("example.SomeClass", SomeClass{}); err != nil {
- panic(err)
- }
- value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}
- value.F3 = value.F2
- value.F1 = value
- bytes, err := fory.Marshal(value)
- if err != nil {
- }
- var newValue interface{}
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
+ f := fory.New(fory.WithXlang(true))
+ if err := f.RegisterStruct(Person{}, 1); err != nil {
+ panic(err)
+ }
+
+ person := &Person{Name: "chaokunyang", Age: 28}
+ data, err := f.Serialize(person)
+ if err != nil {
+ panic(err)
+ }
+
+ var result Person
+ if err := f.Deserialize(data, &result); err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("%s %d\n", result.Name, result.Age)
+}
+```
+
+### Rust
+
+Rust 同样遵循这套跨语言约定,只是通过派生 trait 和在 `Fory` 实例上显式注册来表达。只要类型 ID
与其他运行时一致,载荷就可以安全地跨语言流转。
+
+```rust
+use fory::{Fory, ForyObject};
+use std::error::Error;
+
+#[derive(ForyObject, Debug)]
+struct Person {
+ name: String,
+ age: i32,
+}
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let mut fory = Fory::default().xlang(true);
+ fory.register::<Person>(1)?;
+ // fory.register_by_name::<Person>("example.Person")?;
+
+ let person = Person {
+ name: "chaokunyang".to_string(),
+ age: 28,
+ };
+ let bytes = fory.serialize(&person);
+ let result: Person = fory.deserialize(&bytes)?;
+ println!("{} {}", result.name, result.age);
+ Ok(())
}
```
### JavaScript
-```typescript
-import Fory, { Type } from "@apache-fory/fory";
+JavaScript 的跨语言支持是基于 Schema 描述的。它不是注册类,而是通过 `Type.object(...)`
描述载荷结构,再使用返回的序列化器来编码和解码数据。
+
+这些包目前还没有发布到 npm。因此请先从 Apache Fory 仓库完成构建,再按下面的 API 方式使用。
+
+```javascript
+import Fory, { Type } from "@apache-fory/core";
/**
- * @apache-fory/hps use v8's fast-calls-api that can be called directly by
jit, ensure that the version of Node is 20 or above.
- * Experimental feature, installation success cannot be guaranteed at this
moment
- * If you are unable to install the module, replace it with `const hps = null;`
- **/
+ * `@apache-fory/hps` 会通过 JIT 直接使用 V8 fast calls。
+ * 启用时请使用 Node.js 20+。
+ * 如果安装失败,请将它替换为 `const hps = null;`。
+ */
import hps from "@apache-fory/hps";
-// Now we describe data structures using JSON, but in the future, we will use
more ways.
-const description = Type.object("example.foo", {
- foo: Type.string(),
+const description = Type.object("example.Person", {
+ name: Type.string(),
+ age: Type.int32(),
});
+
const fory = new Fory({ hps });
const { serialize, deserialize } = fory.registerSerializer(description);
-const input = serialize({ foo: "hello fory" });
-const result = deserialize(input);
+
+const payload = serialize({ name: "chaokunyang", age: 28 });
+const result = deserialize(payload);
console.log(result);
```
-### Rust
+### C\#
-```rust
-use fory::{from_buffer, to_buffer, Fory};
+C# 的跨语言代码看起来与原生模式很接近,但运行时需要显式启用 xlang 和 compatible 模式。与此同时,仍然必须与
Java、Go、Swift、Rust 等对端使用相同的类型 ID 或 namespace/name 映射。
-#[derive(Fory, Debug, PartialEq)]
-#[tag("example.foo")]
-struct Animal {
- name: String,
- category: String,
+```csharp
+using Apache.Fory;
+
+[ForyObject]
+public sealed class Person
+{
+ public string Name { get; set; } = string.Empty;
+ public int Age { get; set; }
}
-#[derive(Fory, Debug, PartialEq)]
-#[tag("example.bar")]
-struct Person {
- name: String,
- age: u32,
- pets: Vec<Animal>,
-}
-
-fn main() {
- let penson = Person {
- name: "hello".to_string(),
- age: 12,
- pets: vec![
- Animal {
- name: "world1".to_string(),
- category: "cat".to_string(),
- },
- Animal {
- name: "world2".to_string(),
- category: "dog".to_string(),
- },
- ],
- };
- let bin = to_buffer(&penson);
- let obj: Person = from_buffer(&bin).expect("should success");
- assert_eq!(obj, penson);
+Fory fory = Fory.Builder()
+ .Xlang(true)
+ .Compatible(true)
+ .Build();
+
+fory.Register<Person>(1);
+
+Person person = new() { Name = "chaokunyang", Age = 28 };
+byte[] payload = fory.Serialize(person);
+Person result = fory.Deserialize<Person>(payload);
+
+Console.WriteLine($"{result.Name} {result.Age}");
+```
+
+### Swift
+
+Swift 的跨语言序列化仍然使用与原生模式相同的 `@ForyObject` 模型风格,只是在创建运行时时要传入 `xlang:
true`。要实现互操作,稳定的注册 ID 仍然是最核心的要求。
+
+```swift
+import Fory
+
+@ForyObject
+struct Person: Equatable {
+ var name: String = ""
+ var age: Int32 = 0
+}
+
+let fory = Fory(xlang: true, trackRef: false, compatible: true)
+fory.register(Person.self, id: 1)
+
+let person = Person(name: "chaokunyang", age: 28)
+let data = try fory.serialize(person)
+let result: Person = try fory.deserialize(data)
+
+print("\(result.name) \(result.age)")
+```
+
+### 要点
+
+- 在每个运行时中都显式启用 xlang 模式,例如
`Language.XLANG`、`WithXlang(true)`、`Xlang(true)`、`Fory(xlang: true, ...)` 等。
+- 在所有语言中使用**一致的 ID 或名称**注册类型。
+- 基于 ID 的注册更紧凑、速度更快,但需要集中协调以避免冲突。
+- 基于名称的注册更容易在团队间管理,但载荷会稍大一些。
+- 只使用具备跨语言映射的类型,详见 [Type Mapping](../specification/xlang_type_mapping.md)。
+
+关于跨语言场景中的循环引用、共享引用和多态示例,请参见:
+
+- [跨语言序列化指南](../guide/xlang/index.md)
+- [Go 指南 - 跨语言](../guide/go/cross-language.md)
+- [C# 指南 - 跨语言](../guide/csharp/cross-language.md)
+- [Swift 指南 - 跨语言](../guide/swift/cross-language.md)
+
+## Row Format 编码
+
+Row format 提供零拷贝随机访问能力,非常适合分析型负载和数据处理流水线。
+
+### Java
+
+```java
+import org.apache.fory.format.*;
+import java.util.*;
+import java.util.stream.*;
+
+public class Bar {
+ String f1;
+ List<Long> f2;
+}
+
+public class Foo {
+ int f1;
+ List<Integer> f2;
+ Map<String, Integer> f3;
+ List<Bar> f4;
}
+
+RowEncoder<Foo> encoder = Encoders.bean(Foo.class);
+Foo foo = new Foo();
+foo.f1 = 10;
+foo.f2 = IntStream.range(0, 1000000).boxed().collect(Collectors.toList());
+foo.f3 = IntStream.range(0, 1000000).boxed().collect(Collectors.toMap(i ->
"k"+i, i -> i));
+
+List<Bar> bars = new ArrayList<>(1000000);
+for (int i = 0; i < 1000000; i++) {
+ Bar bar = new Bar();
+ bar.f1 = "s" + i;
+ bar.f2 = LongStream.range(0, 10).boxed().collect(Collectors.toList());
+ bars.add(bar);
+}
+foo.f4 = bars;
+
+// 序列化为 row format(可被 Python 以零拷贝方式读取)
+BinaryRow binaryRow = encoder.toRow(foo);
+
+// 反序列化整个对象
+Foo newFoo = encoder.fromRow(binaryRow);
+
+// 不做完整反序列化,直接零拷贝访问嵌套字段
+BinaryArray binaryArray2 = binaryRow.getArray(1); // 访问 f2 字段
+BinaryArray binaryArray4 = binaryRow.getArray(3); // 访问 f4 字段
+BinaryRow barStruct = binaryArray4.getStruct(10); // 访问第 11 个 Bar 元素
+long value = barStruct.getArray(1).getInt64(5); // 访问嵌套值
+
+// 部分反序列化
+RowEncoder<Bar> barEncoder = Encoders.bean(Bar.class);
+Bar newBar = barEncoder.fromRow(barStruct);
+Bar newBar2 = barEncoder.fromRow(binaryArray4.getStruct(20));
```
+
+### Python
+
+```python
+from dataclasses import dataclass
+from typing import List, Dict
+import pyarrow as pa
+import pyfory
+
+@dataclass
+class Bar:
+ f1: str
+ f2: List[pa.int64]
+
+@dataclass
+class Foo:
+ f1: pa.int32
+ f2: List[pa.int32]
+ f3: Dict[str, pa.int32]
+ f4: List[Bar]
+
+encoder = pyfory.encoder(Foo)
+foo = Foo(
+ f1=10,
+ f2=list(range(1000_000)),
+ f3={f"k{i}": i for i in range(1000_000)},
+ f4=[Bar(f1=f"s{i}", f2=list(range(10))) for i in range(1000_000)]
+)
+
+# 序列化为 row format
+binary: bytes = encoder.to_row(foo).to_bytes()
+
+# 无需完整反序列化即可零拷贝随机访问
+foo_row = pyfory.RowData(encoder.schema, binary)
+print(foo_row.f2[100000]) # 直接访问元素
+print(foo_row.f4[100000].f1) # 访问嵌套字段
+print(foo_row.f4[200000].f2[5]) # 访问更深层的嵌套字段
+```
+
+更多 row format 细节请参见 [Java Row Format 指南](../guide/java/row-format.md) 或
[Python Row Format 指南](../guide/python/row-format.md)。
diff --git
a/static/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png
b/static/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png
index 70a4e1fdd3..4155f8b624 100644
Binary files
a/static/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png
and
b/static/img/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png
differ
diff --git
a/static/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png
b/static/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png
index dcfe30633f..9ea114a36f 100644
Binary files
a/static/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png
and
b/static/img/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png
differ
diff --git
a/static/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png
b/static/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png
index ac161c9dda..079ec78cae 100644
Binary files
a/static/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png
and
b/static/img/benchmarks/deserialization/bench_deserialize_STRUCT_from_directBuffer_tps.png
differ
diff --git
a/static/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png
b/static/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png
index 68fef5a920..1f65fe0f7d 100644
Binary files
a/static/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png
and
b/static/img/benchmarks/deserialization/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png
differ
diff --git
a/static/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png
b/static/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png
index 94529bb833..386091a217 100644
Binary files
a/static/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png
and
b/static/img/benchmarks/deserialization/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png
differ
diff --git
a/static/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png
b/static/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png
index 102aebf71c..5d88e2e96f 100644
Binary files
a/static/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png
and
b/static/img/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png
differ
diff --git
a/static/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png
b/static/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png
index 391a4cd725..83edd359c9 100644
Binary files
a/static/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png
and
b/static/img/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png
differ
diff --git
a/static/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png
b/static/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png
index 0dd0146df5..49f6602f86 100644
Binary files
a/static/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png
and
b/static/img/benchmarks/serialization/bench_serialize_STRUCT_to_directBuffer_tps.png
differ
diff --git
a/static/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png
b/static/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png
index 87782f2b15..edc19b6e00 100644
Binary files
a/static/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png
and
b/static/img/benchmarks/serialization/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png
differ
diff --git
a/static/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png
b/static/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png
index 4093a4a295..7e83e3efb7 100644
Binary files
a/static/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png
and
b/static/img/benchmarks/serialization/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png
differ
diff --git
a/static/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png
b/static/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png
index 9ec2e6c0cc..da83fefcd3 100644
Binary files
a/static/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png
and
b/static/img/benchmarks/zerocopy/zero_copy_bench_deserialize_BUFFER_from_array_tps.png
differ
diff --git
a/static/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png
b/static/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png
index 55834422a6..ea719dc9bf 100644
Binary files
a/static/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png
and
b/static/img/benchmarks/zerocopy/zero_copy_bench_serialize_BUFFER_to_array_tps.png
differ
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]