These 41 commits are when the Protocol Buffers files have changed:
| Commit: | e637cf7 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(rust): support thread safe `Arc<dyn Any + Send + Sync>` type (#3736) ## Why? ## What does this PR do? ## Related issues Closes #3732 ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 8b4439a | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): add java/python gRPC support (#3692) ## Why? Add compiler-generated gRPC support for Fory IDL services so Java and Python users can build gRPC clients and servers directly from FDL, FlatBuffers IDL, and Protobuf service definitions. This also covers the service-related gaps tracked by #3266, #3272, and #3273. ## What does this PR do? - Generates Java grpc-java service classes, method descriptors, async/blocking/future stubs, server bindings, and Fory-backed request/response marshalling. - Generates Python grpcio companion modules with servicer base classes, registration helpers, and unary, server-streaming, client-streaming, and bidirectional-streaming handlers. - Preserves source package metadata during import resolution so service request and response types can be resolved across imported schemas. - Adds validation and codegen tests for service generation, naming collisions, streaming RPCs, imports, Java package options, and Protobuf service translation. - Adds Java/Python gRPC IDL interop fixtures and CI coverage through `integration_tests/idl_tests/run_grpc_tests.sh`. - Updates compiler documentation for service generation and the new `--grpc` integration test generation path. ## Related issues #3266 Closes #3272 Closes #3273 ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 56b5b38 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): set thread_safe_pointer to false by default and enhance ci (#3690) BREAKING CHANGE: Rust IDL ref fields now generate Rc/RcWeak unless thread_safe=true is set, which generates Arc/ArcWeak. ## Why? Rust IDL ref fields do not need cross-thread ownership by default. Using `Rc`/`RcWeak` as the default keeps generated Rust types aligned with the non-thread-safe default while still allowing users to opt into `Arc`/`ArcWeak` when cross-thread sharing is required. ## What does this PR do? - Adds the `thread_safe_pointer` field option to the compiler protobuf extension so protobuf IDL can opt Rust ref fields into `Arc`/`ArcWeak`. - Updates Rust codegen so ref fields, weak refs, list element refs, map value refs, and union payload refs default to `Rc`/`RcWeak` unless `thread_safe=true` is set. - Updates generated-code tests and Rust IDL roundtrip tests to validate the new default pointer mapping and the thread-safe opt-in path. - Refreshes compiler IDL docs for Fory IDL, protobuf IDL, and FlatBuffers IDL with the new Rust pointer carrier behavior. - Adds a dedicated Scala IDL CI job, enables warnings-as-errors for the C++ example builds, and fixes AVX2 constant helpers used by UTF string utilities. ## Related issues ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [x] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | b4441d0 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
docs: update readme (#3664) ## Why? ## What does this PR do? ## Related issues ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 7f8e223 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf: optimize serialization perf (#3656) ## Why? Improve serialization/deserialization throughput across Fory runtimes and keep the cross-language benchmark suite current, comparable, and documented. ## What does this PR do? - Optimizes hot serialization/deserialization paths in JavaScript/TypeScript, Go, C++, C#, Python, and Rust, including ref reset skips, root serializer/deserializer caches, TypeMeta/read-schema caches, string and varint fast paths, small typed-array writes, Go varint32 struct reads, C++ root struct type info caching, C# inline TypeMeta indexes, Python declared ndarray fields, and Rust signed varint encoding. - Adds Java xlang JMH benchmarks with FlatBuffers coverage, generated FlatBuffers sources, a benchmark runner, and a report renderer. - Refreshes benchmark payloads by renaming the simple struct fixture to `NumericStruct`, expanding it to 12 int32 fields, and aligning protobuf/msgpack/json benchmark coverage across languages. - Updates benchmark runners and report generators for C++, C#, Dart, Go, Java, JavaScript, Python, Rust, and Swift, including combined throughput plots, serialized-size output, and regenerated `docs/benchmarks/**` artifacts. - Adds/updates focused coverage for the changed paths, including JavaScript TypeMeta-compatible reader tests and Dart generated benchmark model round-trip tests. ## Related issues #1017 ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark - Refreshes benchmark reports and images under `docs/benchmarks/**` for C++, C#, Dart, Go, Java, JavaScript, Python, Rust, and Swift. - Adds Java xlang throughput reporting; the generated Java report documents JMH parameters: `-f 1 -wi 3 -i 3 -t 1 -w 3s -r 3s -bm thrpt -tu s`.
| Commit: | 3f7a0a5 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(xlang): unified xlang type system (#3644) ## Why? Fory's xlang 1.0 type system needs one canonical schema model for scalar integer encodings, half-precision floating-point types, and dense numeric arrays so IDL/compiler output, runtime annotations, and cross-language peers agree on the same type IDs and wire behavior. ## What does this PR do? - Reworks the xlang type mapping and serialization docs so `varint`, `fixed`, and `tagged` are scalar encoding modifiers, while `list<T>` and dense `array<T>` are distinct schema kinds. - Extends the FDL/FBS compiler IR, parser, validator, emitter, and language generators to support `array<T>`, scalar encoding metadata, and float16/bfloat16 mappings across Java, Python, Go, Rust, C++, C#, JavaScript, Dart, and Swift. - Updates runtimes to handle canonical primitive-array type IDs and array/list semantics, including Java primitive array serializers and annotations, Python dense-array wrappers, Go primitive slice/list support, and related C++/C#/JavaScript/Rust/Swift resolver, skip, union, and field metadata paths. - Expands IDL roundtrip coverage across C++, C#, Dart, Go, Java, JavaScript, Python, Rust, and Swift, with additional compiler, primitive-array, annotation, field metadata, typedef, and serializer tests. - Refreshes specs, guides, README content, integration fixtures, and benchmark models for the new xlang 1.0 type names and array/encoding syntax. ## Related issues #1017 ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? Yes. This updates public xlang/IDL type syntax and mappings, adds array-related annotations/carriers, and changes the documented xlang wire mapping for dense numeric arrays. - [x] Does this PR introduce any public API change? - [x] Does this PR introduce any binary protocol compatibility change? ## Benchmark Not included. Benchmark fixtures were updated to use the new xlang type mapping.
| Commit: | 83b717d | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf(rust): Rewrite Rust benchmarks around shared bench.proto data (#3497) ## Summary - rewrite the Rust benchmark suite around the shared `benchmarks/proto/bench.proto` cases used by the C++ benchmark reference - replace the old Rust-only benchmark model/proto tree with shared data factories plus generic Fory/Protobuf serializers and updated benchmark/report tooling - regenerate `docs/benchmarks/rust/` with the new report and plot set, removing stale old-case artifacts ## Verification - `cd benchmarks/rust && cargo fmt --check` - `cd benchmarks/rust && cargo test --offline` - `cd benchmarks/rust && cargo bench --offline --bench serialization_bench -- struct --noplot` - `cd benchmarks/rust && cargo run --offline --release --bin fory_profiler -- --print-all-serialized-sizes` - `cd benchmarks/rust && CARGO_NET_OFFLINE=true bash ./run.sh`
| Commit: | 550d8ee | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(swift): fory swift schema idl codegen (#3433) ## Why? Swift IDL schema code generation was missing from the compiler workflow. This PR adds Swift generation and the required runtime/test/docs integration so Swift users can generate and validate IDL-based models end-to-end. ## What does this PR do? - Adds Swift as a compiler target with `--lang swift` and `--swift_out`, plus `--swift_namespace_style` support. - Implements `compiler/fory_compiler/generators/swift.py` to generate Swift schema/model code (messages, enums, unions, registration helpers, import-aware references). - Extends compiler option handling (`swift_namespace_style`) and proto extension options, with corresponding parser and generator plumbing. - Adds/updates compiler tests for Swift generation, package options, and CLI option behavior. - Updates Swift runtime and macro logic used by generated code, including compatible metadata/field-ID handling and related serialization/deserialization coverage. - Adds Swift IDL integration test package + runner script and wires Swift/C# IDL runs into CI. - Updates compiler and Swift documentation for Swift codegen usage and generated code behavior. ## Related issues Closes #3357 ## Does this PR introduce any user-facing change? Yes. The compiler now supports Swift schema code generation and new Swift-related CLI/config options. - [x] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | d988a74 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf(swift): add fory swift serialization benchmark and optimize perf (#3395) ## Why? - Add a reproducible Swift benchmark suite across fory/protobuf/msgpack and document current performance. - Optimize Swift serialization/deserialization hot paths without changing the Fory protocol. ## What does this PR do? - Adds a new Swift benchmark suite under `benchmarks/swift`: - benchmark harness, datasets, and runners (`BenchmarkRunner`, `main.swift`) - protobuf schema + generated Swift bindings for parity (`bench.proto`, `bench.pb.swift`) - one-command run script and markdown/plot report generator (`run.sh`, `benchmark_report.py`) - Optimizes Swift runtime hot paths in core serialization/deserialization: - `ByteBuffer` varint/buffer paths - collection/object serializer paths (`CollectionSerializers`, `Serializer`, `Fory`, `Context`, `RefResolver`) - macro and type metadata plumbing updates (`ForyObjectMacro`, `TypeMeta`, `TypeResolver`) - Avoids an extra UTF-8 byte copy in the string decode path. - Refactors type-id naming: `ForyTypeId` -> `TypeId` (`swift/Sources/TypeId.swift`). - Includes CI follow-up fixes: - style-format `benchmarks/swift/benchmark_report.py` - simplify two large `UInt64` varint expressions in `ByteBuffer` to avoid Swift compiler type-check timeout on macOS CI. ## Related issues #3349 #3355 ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. --> ### Swift benchmark result (`benchmarks/swift/results/REPORT.md`) | Key | Value | | --- | --- | | Timestamp | 2026-02-24T09:07:22Z | | OS | Version 15.7.2 (Build 24G325) | | Host | macbook-pro.local | | CPU Cores (Logical) | 12 | | Memory (GB) | 48.00 | | Duration per case (s) | 3 | | Datatype | Operation | Fory TPS | Protobuf TPS | Msgpack TPS | Fastest | | --- | --- | ---: | ---: | ---: | --- | | Struct | Serialize | 6,594,978 | 6,510,524 | 143,221 | fory (1.01x) | | Struct | Deserialize | 21,546,392 | 9,413,296 | 99,321 | fory (2.29x) | | Sample | Serialize | 2,830,973 | 1,292,133 | 16,805 | fory (2.19x) | | Sample | Deserialize | 1,043,252 | 752,382 | 12,515 | fory (1.39x) | | MediaContent | Serialize | 1,487,110 | 667,043 | 28,348 | fory (2.23x) | | MediaContent | Deserialize | 895,491 | 466,411 | 12,605 | fory (1.92x) | | StructList | Serialize | 2,238,338 | 1,019,259 | 24,186 | fory (2.20x) | | StructList | Deserialize | 2,737,618 | 803,488 | 8,600 | fory (3.41x) | | SampleList | Serialize | 600,480 | 195,762 | 3,314 | fory (3.07x) | | SampleList | Deserialize | 170,963 | 123,110 | 1,500 | fory (1.39x) | | MediaContentList | Serialize | 330,343 | 103,388 | 5,472 | fory (3.20x) | | MediaContentList | Deserialize | 173,235 | 86,549 | 1,499 | fory (2.00x) | | Datatype | Fory | Protobuf | Msgpack | | --- | ---: | ---: | ---: | | MediaContent | 287 | 301 | 524 | | MediaContentList | 1435 | 1520 | 2639 | | Sample | 380 | 375 | 737 | | SampleList | 1900 | 1890 | 3698 | | Struct | 28 | 61 | 65 | | StructList | 140 | 315 | 338 |
| Commit: | 64dd156 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
refactor(benchmarks): rename benchmark directories and update links (#3398) ## Why? ## What does this PR do? ## Related issues ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 6f59748 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf: optimize schema evolution mode performance (#3260) ## Why? Improve schema evolution/compatible mode throughput by reducing type-meta lookup overhead and enabling fast-path reads when schemas match, and extend benchmarks to cover list workloads. ## What does this PR do? - C++: optimize compatible-mode type-meta sharing/caching and add a fast-path struct read when schema hashes match; align benchmarks with field tags and compatible mode. - Go: speed up compatible-mode type-meta sharing (uintptr key + first-type fast path), cache TypeInfo for struct/pointer fields and typedefs, and extend benchmarks/reporting for list workloads. - Rust: add schema hash and fast type/meta lookup caches, use a faster vec reader and type-info path, and tag benchmark models + add a benchmark runner script. ## Related issues #1017 #2906 #2982 ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | bf7bc51 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): add evolution option support (#3262) ## Why? - Add a cross-language way to disable schema evolution for stable messages/structs to avoid compatible metadata overhead. - Let IDL files set a default `evolving` behavior that generators and runtimes can honor consistently. ## What does this PR do? - Adds `evolving` to FDL/proto file options and message options, plus generator logic to compute the effective value. - Emits evolving-disabled annotations/macros/decorators in codegen for C++, Go, Java, Python, and Rust (new `@ForyObject` and `pyfory.dataclass` support). - Updates runtime type resolution to choose STRUCT vs COMPATIBLE_STRUCT (and named variants) based on the evolving flag; adds per-language tests for overrides and new IDL roundtrip cases. - Updates schema evolution docs and compiler schema reference; removes the old type-system doc stub. ## Related issues #3099 #1017 #2906 #2982 ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 9891bde | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler/runtime): use hash for generated class as id and refactor user type id encoding (#3248) ## Why? Enable deterministic auto-generated type IDs for FDL/IDL (with optional aliases) so generated code can register by ID without requiring manual IDs for every type. ## What does this PR do? - Add compiler support for auto-generated type IDs (MurmurHash3), package/type aliases, and the `enable_auto_type_id` file option; propagate generated IDs into IR and codegen comments/registration. - Update xlang type metadata/resolvers to carry a separate user type ID (C++/Go/Dart/Java) and adjust type-info encoding and registration flows accordingly. - Improve Go codegen output path resolution by reading `go.mod` when present. - Expand docs and tests (compiler + IDL roundtrip) to cover auto IDs and aliasing. ## Related issues #3099 ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | f534ffe | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): add generated `to_bytes/from_bytes` methods to generated message/union (#3238) ## Why? - Provide convenient bytes helpers on generated IDL types and make registration of imported types consistent across languages. ## What does this PR do? - Generate `to_bytes/from_bytes` (or language equivalents) for IDL messages/unions in C++/Go/Java/Python/Rust and update the generated-code docs/examples. - Add helper registration paths that register imported types first and centralize thread-safe Fory creation. - Add new pools/factories (`SimpleForyPool`, `threadsafe.NewWithFactory`, `ThreadSafeFory` factory) and extend IDL integration tests to round-trip via the new helpers. ## Related issues Closes #3237 #3099 ## Does this PR introduce any user-facing change? Generated IDL code now exposes `to_bytes/from_bytes` helpers and new registration helpers. - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | cf747e8 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(c++): add polymorphic serialization support for `any` to compiler (#3232) ## Why? ## What does this PR do? - Add `any` as a primitive in the compiler IR and proto frontend (including `google.protobuf.Any`), and generate language bindings across C++/Go/Java/Python/Rust with nullable handling. - Introduce C++ `std::any` serialization support plus validator and resolver updates needed for `any`/union handling in xlang. - Add `any` IDL/proto examples, cross-language roundtrip coverage, and docs updates. ## Related issues Closes #3172 Closes #3231 #3099 ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 2e6c57a | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(xlang/compiler): support shared/circular reference serialization for fory/protobuf/flatbuffer idl (#3226) ## Why? Enable IDL schemas to express shared/circular references (including back-pointers) without forcing strong reference cycles, so xlang roundtrips can preserve graph identity safely across languages. ## What does this PR do? - Add `fory/proto/flatbuffer` ref options (including `ref(weak=true)` and thread-safe variants), plus parser/IR/validator support for ref options on fields, list elements, and map values. - Add flatbuffer field attritbutes parse support. - Update compiler codegen (C++/Rust) to emit weak-reference storage where requested; adjust dependency resolution and include handling; add weak ref equality helpers in Rust. - Extend IDL roundtrip coverage with new tree/graph schemas and multi-language tests (Java/Go/Python/Rust/C++), including ref-tracking scenarios. - Update compiler and contributor docs for new ref syntax/behavior and idl_test prerequisites. ## Usage example fory idl: ```proto package tree; message TreeNode { string id = 1; string name = 2; repeated ref TreeNode children = 3; ref(weak=true) TreeNode parent = 4; // back-pointer } ``` protobuf idl: ```proto syntax = "proto3"; package tree; message TreeNode { string id = 1; string name = 2; repeated TreeNode children = 3 [(fory).ref = true]; TreeNode parent = 4 [(fory).weak_ref = true]; } ``` flatbuffer idl: ```flatbuffers namespace tree; table TreeNode { id: string; name: string; children: [TreeNode] (fory_ref: true); parent: TreeNode (fory_weak_ref: true); } ``` ## Cross Language Serialization Examples ### Rust Example Generated code: ```rust #[derive(ForyObject, Debug, Clone, PartialEq, Default)] pub struct TreeNode { #[fory(id = 1)] pub id: String, #[fory(id = 2)] pub name: String, #[fory(id = 3)] pub children: Vec<Arc<TreeNode>>, #[fory(id = 4, nullable = true, ref = true)] pub parent: Option<ArcWeak<TreeNode>>, } ``` Serialization example: ```rust let tree_root = build_tree(); let bytes = ref_fory.serialize(&tree_root).expect("serialize tree"); let roundtrip: tree::TreeNode = ref_fory.deserialize(&bytes).expect("deserialize"); assert_tree(&roundtrip); ``` ### Python Example Generated code: ```python @dataclass class TreeNode: id: str = pyfory.field(id=1, default="") name: str = pyfory.field(id=2, default="") children: List[TreeNode] = pyfory.field(id=3, default_factory=list) parent: Optional[TreeNode] = pyfory.field(id=4, nullable=True, ref=True, default=None) ``` Serialization Example: ```python root = build_tree() data = fory.serialize(root) decoded = fory.deserialize(data) assert isinstance(decoded, tree.TreeNode) assert_tree(decoded) ``` ### Java Example Generated code: ```java public class TreeNode { @ForyField(id = 1) private String id; @ForyField(id = 2) private String name; @ForyField(id = 3) private List<TreeNode> children; @ForyField(id = 4, nullable = true, ref = true) private TreeNode parent; ...getter/setters } ``` Serialization Example: ```java TreeNode tree = buildTree(); byte[] bytes = fory.serialize(tree); Object decoded = fory.deserialize(bytes); ``` ### C++ Example Generated code: ```c++ class TreeNode final { // getters/setters/accessor private: std::string id_; std::string name_; std::vector<std::shared_ptr<TreeNode>> children_; fory::serialization::SharedWeak<TreeNode> parent_; public: FORY_STRUCT(TreeNode, id_, name_, children_, parent_); }; ``` Serialization Example: ```c++ tree::TreeNode tree_root = BuildTree(); FORY_TRY(tree_bytes, ref_fory.serialize(tree_root)); FORY_TRY(tree_roundtrip, ref_fory.deserialize<tree::TreeNode>( tree_bytes.data(), tree_bytes.size())); ``` ### Go Example Generated code: ```go type TreeNode struct { Id string `fory:"id=1"` Name string `fory:"id=2"` Children []*TreeNode `fory:"id=3,nullable=false"` Parent *TreeNode `fory:"id=4,nullable,ref"` } ``` Serialization Example: ```go root := BuildTree() data, err := f.Serialize(&root) if err != nil { t.Fatalf("serialize tree: %v", err) } var out treepkg.TreeNode if err := f.Deserialize(data, &out); err != nil { t.Fatalf("deserialize tree: %v", err) } assertTree(t, out) ``` ## Related issues #3099 #1017 https://github.com/protocolbuffers/protobuf/issues/5504 ## Does this PR introduce any user-facing change? - [x] Does this PR introduce any public API change?: Yes, we use new `ref(weak=true, thread_safe=false)` syntax for ref configuration. - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | 4b02fc5 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(go): use option for optional fields (#3202) ## Why? Align Go codegen/serialization with xlang optional field semantics and add cross-language coverage for optional IDL types. ## What does this PR do? - Generate Go optional fields using `optional.Optional[T]` (including decoder/encoder codegen, struct metadata, and type resolution) instead of pointers where supported. - Add optional-types IDL schema and cross-language roundtrip tests for Java, Go, Python, Rust, and C++ integration tests. - Update C++ timestamp serialization to microsecond precision per spec and expand field-config macro support. - Adjust Python xlang struct fingerprinting for user-defined types and add xlang byte-array read/write helpers. - Ignore generated optional-types artifacts in integration test fixtures. - Make struct object always addressable by copy unaddressable struct into a temp object to remove reflect from whole codepath ## Related issues Closes #3196 ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
| Commit: | c200874 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): add union support to fory compiler and runtime (#3195) ## Why? Fory needs Union type support in its IDL compiler to enable cross-language serialization of sum types (tagged unions). This allows users to define Union types in FDL/Protobuf/FlatBuffers schemas and have the compiler generate code for all supported languages (Java, C++, Python, Go, Rust). ## What does this PR do? This PR adds comprehensive Union type support across the entire Fory stack: **Compiler & IDL:** - Added Union AST node to the IR with support for FDL, Protobuf (oneof), and FlatBuffers (union) - Implemented Union code generation for all languages: Java, C++, Python, Go, and Rust - Added validation and semantic checks for Union types - Updated parsers to recognize Union/oneof/union syntax in FDL, Proto, and FBS formats **Runtime Support:** - Java: Implemented generic UnionSerializer for generated Union classes, supporting Union2-Union6 typed variants - C++: Added union_serializer.h with template-based serialization for unions, integrating with existing std::variant support - Python: Created union.py module with UnionSerializer for dynamic union type handling - Go: Implemented union.go with union type registration and serialization - Rust: Enhanced enum derive macro to generate Union-compatible serialization with proper TypeId normalization **Protocol & Xlang:** - Aligned cross-language Union serialization format: index + ref_flag + type_id + data - Updated xlang specification to document Union type behavior - Added named union support with meta-sharing for efficient type encoding - Implemented skip logic for Union types in all languages **Testing:** - Added integration tests in idl_tests for C++, Go, Java, Python roundtrip validation - Added xlang tests to verify cross-language Union compatibility ## Related issues Closes #3182 #3191 #3170 #1017 #3099 ## Does this PR introduce any user-facing change? Yes. Users can now define Union types in Fory IDL files and use Protobuf oneof or FlatBuffers union syntax which will be compiled to Fory Union types. - [x] Does this PR introduce any public API change? Yes - Adds Union types to the type system - [x] Does this PR introduce any binary protocol compatibility change? No - Union uses existing TypeId (31) from xlang spec ## Benchmark No performance regression expected. Union serialization uses the same optimized paths as existing reference serialization with additional index metadata.
| Commit: | ce0e5d3 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(compiler): add flatbuffers idl support (#3184) ## Why? Currently, Fory compiler only supports its native FDL format and Protocol Buffers. Users who have existing FlatBuffers schemas or prefer FlatBuffers IDL syntax cannot leverage Fory's high-performance serialization without manually converting their schemas. This creates friction for teams migrating from FlatBuffers to Fory or those who want to use FlatBuffers IDL as their schema definition language. ## What does this PR do? This PR adds comprehensive FlatBuffers IDL support to the Fory compiler, enabling users to define schemas using `.fbs` files and generate serialization code through Fory's compilation pipeline. ### Key Features 1. **FlatBuffers IDL Parser**: Complete lexer and recursive descent parser for FlatBuffers `.fbs` files - Supports namespaces, includes, attributes, enums, structs, and tables - Parses field attributes like `deprecated`, `priority`, default values - Error reporting with line/column information 2. **IR Translator**: Translates FlatBuffers AST to Fory IR - `struct` → Fory struct with `evolving=false` (fixed layout) - `table` → Fory struct with `evolving=true` (schema evolution supported) - Field attributes map to Fory field options - Auto-growing field IDs based on declaration order (for schema compatibility) 3. **Scalar Type Mapping**: | FlatBuffers | Fory Type | |------------|-----------| | `byte` | `int8` | | `ubyte` | `uint8` | | `short` | `int16` | | `ushort` | `uint16` | | `int` | `varint32`| | `uint` | `var_uint32` | | `long` | `varint64`| | `ulong` | `var_uint64` | | `float` | `float32` | | `double` | `float64` | | `bool` | `bool` | | `string` | `string` | | `[T]` | `list<T>` | 4. **Unsigned Array Support**: Added cross-language unsigned array type annotations - Java: `@Uint8ArrayType`, `@Uint16ArrayType`, `@Uint32ArrayType`, `@Uint64ArrayType`, `@Int8ArrayType` - Python: `Uint8Array`, `Uint16Array`, `Uint32Array`, `Uint64Array`, `Int8Array` type hints - Enables FlatBuffers `[ubyte]`, `[ushort]`, `[uint]`, `[ulong]` to serialize correctly across languages 5. **Cross-Language Field ID Support**: Extended fingerprint computation to include field IDs for stable cross-language type compatibility ### Usage ```bash # Compile FlatBuffers schema fory compile schema.fbs --lang java,python --output ./generated # Inspect translated FDL for debugging fory compile schema.fbs --emit-fdl --emit-fdl-path ./translated ``` ### Example **Input (FlatBuffers):** ```fbs namespace MyGame; enum Color : byte { Red = 0, Green, Blue } struct Vec3 { x: float; y: float; z: float; } table Monster { pos: Vec3; mana: short = 150; hp: short = 100; name: string; friendly: bool = false (deprecated, priority: 1); inventory: [ubyte]; color: Color = Blue; } ``` **Generated (Java):** ```java public class Monster { @ForyField(id = 0) private Vec3 pos; @ForyField(id = 1) private short mana; @ForyField(id = 2) private short hp; @ForyField(id = 3) private String name; @ForyField(id = 4) private boolean friendly; @ForyField(id = 5) @Uint8ArrayType private byte[] inventory; @ForyField(id = 6) private Color color; // getters/setters... } ``` ## Related issues Closes #3171 Related: #3099, #1197, #1017 ## Does this PR introduce any user-facing change? - **New API**: FlatBuffers IDL support in `fory compile` command - **New Annotations**: Java unsigned array type annotations (`@Uint8ArrayType`, etc.) - **New Types**: Python unsigned array type hints (`Uint8Array`, etc.) **No breaking changes** - all existing FDL and Protobuf workflows continue to work unchanged. ## Does this PR introduce any binary protocol compatibility change? No. The generated code uses the same Fory serialization format. The FlatBuffers support is purely a schema definition convenience - the wire format remains Fory's binary protocol, not FlatBuffers wire format.
| Commit: | d82d97f | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
refactor(compiler): refactor fory compiler into hierarchical architecture (#3179) ## Why? The current Fory compiler mixes FDL-native and protobuf-compatible syntax handling in a single parser, making it difficult to add support for new IDL formats like .proto and .fbs files. The validation logic is scattered across parsing and Schema.validate(), and there's no clear separation between parsing, semantic analysis, and code generation. ## What does this PR do? This PR refactors the Fory compiler into a hierarchical, multi-frontend architecture that establishes the Fory IDL AST as the **canonical intermediate representation (IR)**, with separate frontend parsers for different IDL formats. **Key changes:** 1. **New directory structure** with clear separation of concerns: - `ir/` - Intermediate Representation (canonical Fory AST) - `ast.py` - Core AST node definitions with `SourceLocation` tracking - `types.py` - Extended type system (primitives including varint, tagged types, etc.) - `validator.py` - Centralized semantic validation - `emitter.py` - FDL text emitter for debugging translated schemas - `frontend/` - IDL Frontends - `base.py` - Base frontend interface - `fdl/` - FDL Frontend (lexer + parser) - `proto/` - Protobuf Frontend (lexer + parser + translator to Fory IR) - `fbs/` - FlatBuffers Frontend (placeholder) 2. **Proto3 frontend** - Full support for parsing `.proto` files and translating to Fory IR: - Proto3 syntax parsing (messages, enums, nested types, maps, repeated fields) - Type mapping (int32→var_uint32, sint32→varint32, fixed32→uint32, etc.) - Fory extension options (`(fory).id`, `(fory).ref`, `(fory).nullable`, etc.) - Well-known types support (google.protobuf.Timestamp, Duration) 3. **Simplified FDL syntax** - Removed protobuf-style `(fory)` prefix from options: - File options: `option use_record_for_java_message = true;` - Type options: `message Foo [id=100] { ... }` - Field options: `MyType data = 1 [ref=true, nullable=true];` 4. **Extended type system** with new primitive kinds: - Signed/unsigned variants: `int8`-`int64`, `uint8`-`uint64` - Variable-length encoding: `varint32`, `varint64`, `var_uint32`, `var_uint64` - Tagged types: `tagged_int64`, `tagged_uint64` - Additional types: `float16`, `duration`, `decimal` 5. **Improved code generators** for all target languages with better type mapping 6. **CLI enhancements**: - Auto-detect input format by file extension (`.fdl`, `.proto`) - New `--emit-fdl` flag to output translated FDL for debugging 7. **Cross-language integration tests** for proto-based schemas ## Related issues Closes #3178 ## Does this PR introduce any user-facing change? - CLI now accepts `.proto` files directly (in addition to `.fdl`) - FDL syntax simplified: `option (fory).xxx` → `option xxx` - New primitive types available in FDL - [x] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark N/A - This is a compiler refactoring that doesn't affect runtime performance.
| Commit: | 1cf3827 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(xlang): fory schema idl and compiler (#3106) ## Why? Fory has lacked a schema-first Interface Definition Language (IDL) for cross-language serialization. Currently, teams must manually craft type registration and cross-language models. This is Ok and perfered option if we are suign one language to build the system, since we can **serialize domain object directly.** But it is error-prone when we have multiple languages due to the **type system inconsistency** and makes it difficult to guarantee consistent schemas, type IDs, and reference-tracking behavior across languages. Users who want to migrate from Protocol Buffers to Fory for better performance, reference tracking, or polymorphism support had to manually define structs in every language. This PR addresses this gap by introducing FDL (Fory Definition Language) - a native schema IDL specifically designed for Fory's cross-language serialization capabilities. **Key motivations:** - Enable schema-first development workflow for Fory - Provide deterministic, cross-language type IDs and registration rules - Generate native code with minimal/no runtime overhead - Ensure consistent reference-tracking and polymorphism behavior across languages - Simplify migration from Protocol Buffers by supporting similar syntax patterns ## What does this PR do? ### 1. FDL (Fory Definition Language) Specification - Defines file structure: `package`, `import`, `enum`, `message` - Supports field modifiers: `optional`, `ref`, `repeated` - Supports collection types: `repeated` (list), `map<K,V>` - Supports nested types (message within message, enum within message) - Supports `reserved` names/IDs for backward compatibility - Supports file/type/field `options` (protobuf-style and bracket-style) ### 2. Compiler Frontend (Python-based) - **Hand-written Lexer** (`fory_compiler/parser/lexer.py`): Tokenizes FDL source files - **Recursive-Descent Parser** (`fory_compiler/parser/parser.py`): Parses tokens into AST - **AST/IR Definitions** (`fory_compiler/parser/ast.py`): Schema, Message, Enum, Field, Import, and type representations - **Schema Validation**: Detects duplicate names, duplicate IDs, unknown type references, duplicate field numbers - **Import Resolution**: Supports relative and search-path based imports - **Circular Import Detection**: Prevents infinite recursion in imports ### 3. Multi-Language Code Generation | Language | Output | Features | |----------|--------|----------| | **Java** | POJOs with Fory annotations | Getters/setters, equals/hashCode, registration helper class, nested type support | | **Python** | Dataclasses with type hints | Native type mappings, registration function, nested type flattening | | **Go** | Structs with struct tags | Fory struct tags, registration function, nested type flattening | | **Rust** | Structs with derive macros | `#[derive(Fory, ...)]`, registration function, nested type flattening | | **C++** | Structs with FORY macros | `FORY_STRUCT`, `FORY_FIELD_INFO`, registration helper, nested type support | ### 4. Compiler CLI & Build Integration - **CLI command**: `fory compile` with comprehensive options - **Language-specific output directories**: `--java_out`, `--python_out`, `--go_out`, `--rust_out`, `--cpp_out` - **Include paths**: `-I/--proto_path` for import resolution - **Package installable**: `pip install -e .` with `fory` entrypoint ### 5. C++ Improvements - Added `FORY_PP_IS_EMPTY`, `FORY_PP_HAS_ARGS` macros for empty struct support - Added `FORY_STRUCT_0` variant to support structs with no fields - Fixed `FORY_STRUCT` macro to detect empty argument lists ### 6. Integration Tests - Full cross-language roundtrip tests in `integration_tests/idl_tests/` - Tests cover Java ↔ Python ↔ Go ↔ Rust ↔ C++ serialization compatibility - CI workflow integration for all language combinations ### 7. Comprehensive Documentation - FDL Overview - Introduction and quick start - FDL Syntax Reference - Complete language syntax -Type System - Primitive types, collections, and mappings - Compiler Guide - CLI usage and build integration - Generated Code - Output format for each language - Protocol Buffers vs FDL - Feature comparison and migration guide ### Example FDL Schema ```protobuf package addressbook; message Person [id=100] { string name = 1; int32 id = 2; string email = 3; repeated string tags = 4; map<string, int32> scores = 5; enum PhoneType [id=101] { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber [id=102] { string number = 1; PhoneType phone_type = 2; } repeated PhoneNumber phones = 6; } message AddressBook [id=103] { repeated Person people = 1; map<string, Person> people_by_name = 2; } ``` ## Related issues Closes #3163 #3164 #3165 #3167 #3168 #3169 #3173 #3174 #3175 #3176 #3177 #1197 #1945 #3099 ## Does this PR introduce any user-facing change? Yes, this PR introduces a new FDL compiler tool that can be installed via pip: ```bash cd compiler pip install -e . fory compile --lang java,python,go,rust,cpp schema.fdl -o output/ ``` - [x] Does this PR introduce any public API change? - New `fory compile` CLI command - New FDL schema language specification - Generated code uses existing Fory APIs (annotations, macros, derive macros) - [ ] Does this PR introduce any binary protocol compatibility change? - No changes to the serialization protocol - Generated code uses standard Fory serialization ## Benchmark N/A - This PR focuses on code generation tooling. The generated code uses existing Fory serialization APIs which have been benchmarked separately. The compiler itself is a build-time tool and does not impact runtime serialization performance.
| Commit: | b03ee1a | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | chaokunyang | |
chore: move benchmarks to separate dir to speed up ci build (#2894) ## Why? <!-- Describe the purpose of this PR. --> ## What does this PR do? move benchmarks to separate dir to speed up rust ci build, we don't need to run it in ci. ## Related issues #2889 ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. -->
| Commit: | 7b94fe5 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(c++ ): add cpp benchmark (#2943) ## What does this PR do? add cpp benchmarks ## Related issues #2906 ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. -->
| Commit: | daca4e3 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
docs: fix rust benchmark links (#2896) <!-- **Thanks for contributing to Apache Fory™.** **If this is your first time opening a PR on fory, you can refer to [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).** Contribution Checklist - The **Apache Fory™** community has requirements on the naming of pr titles. You can also find instructions in [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). - Apache Fory™ has a strong focus on performance. If the PR you submit will have an impact on performance, please benchmark it first and provide the benchmark result here. --> ## Why? <!-- Describe the purpose of this PR. --> ## What does this PR do? <!-- Describe the details of this PR. --> ## Related issues <!-- Is there any related issue? If this PR closes them you say say fix/closes: - #xxxx0 - #xxxx1 - Fixes #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. -->
| Commit: | c8468b3 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
chore: move benchmarks to separate dir to speed up ci build (#2894) ## Why? <!-- Describe the purpose of this PR. --> ## What does this PR do? move benchmarks to separate dir to speed up rust ci build, we don't need to run it in ci. ## Related issues #2889 ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. -->
| Commit: | b14747c | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
feat(rust): add fory rust benchmark (#2583) ## Why? add fory rust benchmark ## What does this PR do? This benchmark report analyzes the performance of the Fury Rust serialization library compared to Protocol Buffers and JSON serialization across multiple data types and sizes. The benchmark was conducted using Criterion.rs with 100 samples per test, and shows significant performance improvements across all serialization formats. ## Related issues <!-- Is there any related issue? If this PR closes them you say say fix/closes: - #xxxx0 - #xxxx1 - Fixes #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark ## Benchmark Configuration - **Framework**: Criterion.rs with 100 samples per benchmark - **Data Sizes**: Small, Medium, and Large variants for each data type - **Serialization Formats**: Fury, Protocol Buffers (protobuf), and JSON - **Operations**: Both serialization (encode) and deserialization (decode) - **Test Environment**: Release build with optimizations enabled ## Data Types Tested 1. **Simple Struct** - Basic structured data 2. **Person** - Complex nested structures with relationships 3. **Company** - Enterprise-level data structures 4. **ECommerce Data** - Real-world e-commerce transaction data 5. **System Data** - System monitoring and telemetry data ### 1. Simple Struct Performance | Operation | Size | Fury (ns) | Protobuf (ns) | JSON (ns) | Fury vs Protobuf | Fury vs JSON | |-----------|------|-----------|---------------|-----------|------------------|--------------| | **Serialize** | Small | 624.88 | 378.09 | 342.40 | 65% slower | 83% slower | | **Serialize** | Medium | 683.38 | 499.77 | 316.37 | 37% slower | 2.2x slower | | **Serialize** | Large | 756.61 | 440.63 | 644.30 | 72% slower | 17% slower | | **Deserialize** | Small | 140.20 | 111.09 | 219.30 | 26% slower | 36% faster | | **Deserialize** | Medium | 163.63 | 108.89 | 238.74 | 50% slower | 31% faster | | **Deserialize** | Large | 258.13 | 124.86 | 266.82 | 2.1x slower | 3% slower | **Key Insights:** - Fury deserialization is competitive with JSON for small/medium data - Protobuf consistently outperforms Fury in serialization speed - Fury shows better deserialization performance vs JSON for smaller datasets ### 2. Person Data Performance | Operation | Size | Fury (ns) | Protobuf (ns) | JSON (ns) | Fury vs Protobuf | Fury vs JSON | |-----------|------|-----------|---------------|-----------|------------------|--------------| | **Serialize** | Small | 1.1800 µs | 2.1962 µs | 2.2365 µs | 46% faster | 47% faster | | **Serialize** | Medium | 1.9331 µs | 8.1873 µs | 8.7357 µs | 4.2x faster | 4.5x faster | | **Serialize** | Large | 5.1555 µs | 34.879 µs | 36.953 µs | 6.8x faster | 7.2x faster | | **Deserialize** | Small | 2.5146 µs | 1.9148 µs | 2.4461 µs | 31% slower | 3% slower | | **Deserialize** | Medium | 10.940 µs | 10.704 µs | 11.174 µs | 2% slower | 2% faster | | **Deserialize** | Large | 46.603 µs | 46.363 µs | 49.479 µs | 1% slower | 6% faster | **Key Insights:** - Fury dominates serialization performance for complex Person data - Performance advantage increases dramatically with data size - Deserialization performance is competitive across all formats ### 3. Company Data Performance | Operation | Size | Fury (ns) | Protobuf (ns) | JSON (ns) | Fury vs Protobuf | Fury vs JSON | |-----------|------|-----------|---------------|-----------|------------------|--------------| | **Serialize** | Small | 1.4226 µs | 3.6397 µs | 3.9528 µs | 2.6x faster | 2.8x faster | | **Serialize** | Medium | 11.503 µs | 86.868 µs | 94.272 µs | 7.5x faster | 8.2x faster | | **Serialize** | Large | 438.51 µs | 3.7376 ms | 3.9253 ms | 8.5x faster | 9.0x faster | | **Deserialize** | Small | 3.6799 µs | 4.2136 µs | 4.1344 µs | 13% faster | 11% faster | | **Deserialize** | Medium | 114.35 µs | 113.60 µs | 122.22 µs | 1% faster | 6% faster | | **Deserialize** | Large | 4.8316 ms | 4.7077 ms | 4.7859 ms | 3% slower | 1% faster | **Key Insights:** - Fury shows exceptional serialization performance for enterprise data - Massive performance gains (up to 9x) for large Company datasets - Deserialization performance is competitive across all sizes ### 4. ECommerce Data Performance | Operation | Size | Fury (ns) | Protobuf (ns) | JSON (ns) | Fury vs Protobuf | Fury vs JSON | |-----------|------|-----------|---------------|-----------|------------------|--------------| | **Serialize** | Small | 3.1720 µs | 13.209 µs | 14.856 µs | 4.2x faster | 4.7x faster | | **Serialize** | Medium | 79.276 µs | 561.92 µs | 613.57 µs | 7.1x faster | 7.7x faster | | **Serialize** | Large | 1.4452 ms | 12.525 ms | 12.932 ms | 8.7x faster | 8.9x faster | | **Deserialize** | Small | 14.741 µs | 13.615 µs | 16.275 µs | 8% slower | 9% faster | | **Deserialize** | Medium | 752.34 µs | 705.19 µs | 834.59 µs | 7% slower | 10% faster | | **Deserialize** | Large | 12.897 ms | 13.061 ms | 15.304 ms | 1% faster | 16% faster | **Key Insights:** - Fury demonstrates outstanding serialization performance for real-world data - Consistent 4-9x speedup over alternatives - Deserialization performance remains competitive ### 5. System Data Performance | Operation | Size | Fury (ns) | Protobuf (ns) | JSON (ns) | Fury vs Protobuf | Fury vs JSON | |-----------|------|-----------|---------------|-----------|------------------|--------------| | **Serialize** | Small | 2.2199 µs | 6.2741 µs | 7.1390 µs | 2.8x faster | 3.2x faster | | **Serialize** | Medium | 34.718 µs | 260.01 µs | 273.80 µs | 7.5x faster | 7.9x faster | | **Serialize** | Large | 516.34 µs | 3.7771 ms | 3.6049 ms | 7.3x faster | 7.0x faster | | **Deserialize** | Small | 6.3551 µs | 5.6267 µs | 6.8910 µs | 13% slower | 8% faster | | **Deserialize** | Medium | 306.26 µs | 287.02 µs | 391.41 µs | 7% slower | 22% faster | | **Deserialize** | Large | 4.9874 ms | 4.1081 ms | 5.2107 ms | 21% slower | 4% faster | **Key Insights:** - Fury excels at serializing system telemetry data - Strong performance gains (7-8x) for medium and large datasets - Deserialization shows mixed results vs protobuf but beats JSON ## Performance Trends Analysis ### Serialization Performance 1. **Fury Advantage**: Fury consistently outperforms both protobuf and JSON for complex data structures 2. **Scaling**: Performance advantage increases with data complexity and size 3. **Best Cases**: 8-9x speedup for large, complex datasets (Company, ECommerce) 4. **Weakness**: Simple struct serialization shows Fury is slower than alternatives ### Deserialization Performance 1. **Competitive**: Fury deserialization is generally competitive with protobuf 2. **JSON Advantage**: Fury consistently beats JSON deserialization 3. **Consistency**: Performance is more consistent across data types than serialization ### Data Size Impact - **Small Data**: Mixed results, sometimes slower than protobuf - **Medium Data**: Clear Fury advantages emerge (3-7x speedup) - **Large Data**: Fury dominates with 6-9x performance improvements ## Statistical Confidence All benchmark results show statistical significance with p < 0.05, indicating reliable performance measurements. The benchmarks used 100 samples each, providing robust statistical confidence. ## Key Recommendations 1. **Use Fury for Complex Data**: Fury excels with nested, complex data structures 2. **Consider Alternatives for Simple Data**: For basic structs, protobuf may be faster 3. **Leverage Serialization Strengths**: Fury's serialization performance is exceptional 4. **Evaluate Deserialization Trade-offs**: Consider the 10-20% deserialization overhead vs protobuf ## Conclusion The Fury Rust serialization library demonstrates exceptional performance for complex, real-world data structures, with serialization speedups of 4-9x over alternatives. While simple data structures may benefit from protobuf's optimizations, Fury's performance advantage increases dramatically with data complexity, making it an excellent choice for enterprise applications with rich data models. The consistent performance improvements across all data types and sizes, combined with competitive deserialization performance, position Fury as a compelling choice for high-performance Rust applications requiring efficient data serialization. ## Why Fury is Slower for Simple Struct ### Root Cause Analysis Fury's slower performance for simple structs is due to its **rich metadata system** designed for complex, evolving schemas: #### 1. Metadata Overhead - **Header**: 10 bytes (bitmap, language, meta offset) - **Ref Flag**: 1 byte per field - **Type ID**: Variable-length encoding per field (2+ bytes) - **Type Metadata**: Field names, types, and encoding information stored separately - **Total overhead**: ~22+ bytes + metadata vs protobuf's ~4 bytes
The documentation is generated from this commit.
| Commit: | 248ca39 | |
|---|---|---|
| Author: | Asnowww | |
| Committer: | Shawn Yang | |
chore: translate Chinese comments into English (#2503) <!-- **Thanks for contributing to Fory.** **If this is your first time opening a PR on fory, you can refer to [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).** Contribution Checklist - The **Apache Fory** community has requirements on the naming of pr titles. You can also find instructions in [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). - Fory has a strong focus on performance. If the PR you submit will have an impact on performance, please benchmark it first and provide the benchmark result here. --> ## What does this PR do? <!-- Describe the purpose of this PR. --> chore: translate Chinese comments into English ## Related issues <!-- Is there any related issue? Please attach here. - #xxxx0 - #xxxx1 - #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
| Commit: | f412c24 | |
|---|---|---|
| Author: | Asnowww | |
| Committer: | mubai | |
chore: translate Chinese comments into English (#2503) <!-- **Thanks for contributing to Fory.** **If this is your first time opening a PR on fory, you can refer to [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).** Contribution Checklist - The **Apache Fory** community has requirements on the naming of pr titles. You can also find instructions in [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). - Fory has a strong focus on performance. If the PR you submit will have an impact on performance, please benchmark it first and provide the benchmark result here. --> ## What does this PR do? <!-- Describe the purpose of this PR. --> chore: translate Chinese comments into English ## Related issues <!-- Is there any related issue? Please attach here. - #xxxx0 - #xxxx1 - #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
| Commit: | 5673703 | |
|---|---|---|
| Author: | Asnowww | |
| Committer: | GitHub | |
chore: translate Chinese comments into English (#2503) <!-- **Thanks for contributing to Fory.** **If this is your first time opening a PR on fory, you can refer to [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).** Contribution Checklist - The **Apache Fory** community has requirements on the naming of pr titles. You can also find instructions in [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). - Fory has a strong focus on performance. If the PR you submit will have an impact on performance, please benchmark it first and provide the benchmark result here. --> ## What does this PR do? <!-- Describe the purpose of this PR. --> chore: translate Chinese comments into English ## Related issues <!-- Is there any related issue? Please attach here. - #xxxx0 - #xxxx1 - #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
| Commit: | 3fa34b9 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
chore: rename apache fury to apache fory (#2263) ## What does this PR do? Based on the discussion and vote in Fury PPMC and ASF trademark group, Apache Fury will renamed to Apache Fory. This PR renames all fury in the codebase to fory. ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fury/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
| Commit: | a8a140b | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf(java): add struct benchmark with pb (#1736) ## What does this PR do? add struct benchmark with pb: Perf: ``` Benchmark Mode Cnt Score Error Units fury_deserialize thrpt 30 49667.900 ± 3004.061 ops/s fury_kv_compatible_deserialize thrpt 30 33014.595 ± 3716.199 ops/s fury_kv_compatible_serialize thrpt 30 23915.260 ± 3968.119 ops/s fury_serialize thrpt 30 63146.826 ± 2930.505 ops/s protobuf_deserialize thrpt 30 14156.610 ± 685.272 ops/s protobuf_serialize thrpt 30 10060.293 ± 706.064 ops/s ``` Lib | Size -- | -- fury | 8077 furystrict | 8009 furykv | 48028 protobuf | 18000 <br class="Apple-interchange-newline">   ## Related issues <!-- Is there any related issue? Please attach here. - #xxxx0 - #xxxx1 - #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fury/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
| Commit: | bf092cf | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf(java): rename fury-benchmark to benchmark (#1319) This PR renames fury-benchmark to benchmark to keep benchmark module naming consisitent with other languages
| Commit: | bcd3665 | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
perf(java): merge perftests into benchmark (#1318)
| Commit: | 39f5e18 | |
|---|---|---|
| Author: | tison | |
| Committer: | GitHub | |
chore: relocate Maven GAV and Java package (#1259) Signed-off-by: tison <wander4096@gmail.com>
| Commit: | c0d8b9d | |
|---|---|---|
| Author: | Shawn Yang | |
| Committer: | GitHub | |
Update apache license (#1246) ## What do these changes do? Since Fury has joined apache incubator, we need to update license to ASF license <!-- Please give a short brief about these changes. --> ## Related issue number <!-- Are there any issues opened that will be resolved by merging this change? --> Closes #xxxx ## Check code requirements - [ ] tests added / passed (if needed) - [ ] Ensure all linting tests pass, see [here](https://github.com/alipay/fury/blob/main/CONTRIBUTING.rst) for how to run them
| Commit: | 9cd196f | |
|---|---|---|
| Author: | Shawn | |
| Committer: | GitHub | |
[Java] Refactor integration tests (#845) * refactor into jdk_compatibility_tests and perftests * lint code * add integration_tests readme * Fix headers * add logs integration_tests * add logs integration_tests * fxi groupId * remove java version * suppress maven download logs by --no-transfer-progress * suppress maven download logs by --no-transfer-progress * fix path * fix integration_tests
| Commit: | e3d21c2 | |
|---|---|---|
| Author: | tison | |
| Committer: | GitHub | |
chore: apply license format (#783) * chore: apply license format Signed-off-by: tison <wander4096@gmail.com> * ci: check license header Signed-off-by: tison <wander4096@gmail.com> * fix ci scripts Signed-off-by: tison <wander4096@gmail.com> * cargo fmt Signed-off-by: tison <wander4096@gmail.com> * apply suggestions Signed-off-by: tison <wander4096@gmail.com> * style Signed-off-by: tison <wander4096@gmail.com> * format Signed-off-by: tison <wander4096@gmail.com> * add license header instructions Signed-off-by: tison <wander4096@gmail.com> * retains more derived files header Signed-off-by: tison <wander4096@gmail.com> * txt unrelated Signed-off-by: tison <wander4096@gmail.com> --------- Signed-off-by: tison <wander4096@gmail.com> Co-authored-by: chaokunyang <shawn.ck.yang@gmail.com>
| Commit: | a52b8b7 | |
|---|---|---|
| Author: | weipeng | |
| Committer: | GitHub | |
[JavaScript] update benchmark (#597) feat: update benchmark
| Commit: | cb2dce1 | |
|---|---|---|
| Author: | weipeng | |
| Committer: | GitHub | |
[JavaScript] update benchmark (#574) feat: update benchmark
| Commit: | 8f35f5d | |
|---|---|---|
| Author: | weipeng | |
| Committer: | GitHub | |
[JavaScript] improve write performance (#538)
| Commit: | a05fe39 | |
|---|---|---|
| Author: | Shawn | |
| Committer: | GitHub | |
[Java] Add flatbufffer/protobuffer benchmarks (#415) * add integration_tests project * add flatbuffer IDL * add generated flatbuffer files * add Example pojo * add flatbuffer state and conversion from.to java object * add protobuffer state and conversion from.to java object * add usertype benchmark for pb/fb * add tests * fix pom * fix proto generation