🚀 Apache Fory 0.13.0 重磅发布! 这一版本带来两大震撼更新:
- Rust 首个正式版本 :完整高性能序列化栈、Dynamic Trait Object、多集合支持与 Schema 演进能力,让静态语言拥有动态序列化的灵活性。 在性能测试中,比 JSON/Protobuf 快最多 10 倍,压缩率媲美 Protobuf。
- Python Pickle 全面替代方案 :无缝兼容
pickle/cloudpickleAPI,同时做到 更快⚡、更小📦、更安全,支持本地函数/类、lambda、零拷贝 NumPy/Pandas 等高级场景。
无论是跨语言服务还是单语言优化,Fory 都能让数据传输更高效、更可靠。 立即升级,体验 Rust 与 Python 序列化的全新时代!
亮点 🚀
- 🧠 Rust 的 Dynamic Trait Object 序列化
- 🔁 Rust 的 Shared/Circular ownership 序列化
- 🔮 Rust 的 Schema Forward/Backward compatibilify
- 🐍 Python
pickle的 Drop-in Replacement:支持本地函数/类/__reduce__/__getstate__序列化 - 🧾 支持 Python dataclass Schema 向前向后兼容性
- ☕️ Java xlang 模式支持 jit codegen,加速跨语言序列化性能
- ⚙️ 使用 SIMD 的 primitive array compression,大幅压缩数组的序列化体积
- 📦 Row Format 新增 Compact Row Codec,编码压缩率提升50%
- 🐹 支持Go Struct Schema 向前向后兼容性
- 🚀 Golang struct 序列化 的 ahead-of-time codegen,加速 Golang 序列化性能
Rust:首个发布亮点 🦀
这是 Apache Fory 首个 Rust 正式版本,带来完整、高性能的序列化栈。如果你正在构建 Rust 服务或库,现在可以在强类型、性能和 schema 演进方面原生使用 Fory。
- 通过
#[derive(ForyObject)]实现 derive-based object graph serialization - 支持 trait objects 的多态:
Box<dyn Trait>、Rc<dyn Trait>、Arc<dyn Trait>,以及dyn Any Rc/Arc与RcWeak/ArcWeak的共享与循环引用追踪- 提供向前/向后兼容的 schema 演进(Compatible 模式)
- 借助
#[derive(ForyRow)]和按需字段访问,实现零拷贝 Row format - 线程安全并支持多线程序列化(context pool)
- 广泛的集合支持(例如
VecDeque、LinkedList、BTreeMap、BTreeSet、BinaryHeap)
快速上手(最小示例):
use fory::{Fory, Error};
use fory::ForyObject;
#[derive(ForyObject, Debug, PartialEq)]
struct User {
name: String,
age: i32,
email: String,
}
fn main() -> Result<(), Error> {
let mut fory = Fory::default();
fory.register::<User>(1)?;
let user = User { name: "Alice".into(), age: 30, email: "alice@example.com".into() };
let bytes = fory.serialize(&user)?;
let decoded: User = fory.deserialize(&bytes)?;
assert_eq!(user, decoded);
Ok(())
}
- 指南:Rust Serialization – fory.apache.org/docs/docs/g…
- Crate:fory on crates.io – crates.io/crates/fory
- API 文档:docs.rs – docs.rs/fory/latest…
Rust 基准测试 📊
下表展示了在多个数据集和规模上,Fory 与 JSON、Protobuf 的序列化吞吐量(TPS,越高越好)对比,结果表明 Fory 性能是 Protobuf/JSON的10倍以上,序列化结果大小跟 Protobuf Rust 持平:
注意:结果会受到硬件、数据集和实现版本的影响。参阅 Rust 指南了解如何自行运行基准测试:github.com/apache/fory…
Python:pickle 的替代方案 🐍
pyfory 现在是一款高性能的 pickle/cloudpickle Drop-in Replacement,同时保持一致的简洁 API,并增强安全性与性能。
- 在 Python-native 模式(
xlang=False)下序列化任意 Python 对象:全局/本地函数、lambdas、全局/本地类、实例/类/静态方法 - 遵循 Python 钩子:
__getstate__、__setstate__、__reduce__、__reduce_ex__ - 通过
ref=True提供共享/循环对象图的引用追踪 - 借助协议 5 的 out-of-band buffers 和
pickle.PickleBuffer实现零拷贝(如 NumPy、Pandas 等) - 安全性:
strict=True支持基于注册的安全策略,DeserializationPolicy提供精细化管控 - 线程:
ThreadSafeFory支持多线程安全使用 - 熟悉的 API:
dumps/loads是serialize/deserialize的别名
快速上手:
import pyfory
# Drop-in replacement for pickle/cloudpickle
fory = pyfory.Fory(xlang=False, ref=True, strict=False)
def make_multiplier(k):
def mul(x):
return k * x
return mul
binary = fory.dumps(make_multiplier(10))
assert fory.loads(binary)(3) == 30
延伸阅读:Python Guide – fory.apache.org/docs/latest…
📦 快速开始
默认情况下会使用各语言的原生模式以获得最佳性能;只有在需要跨语言互通时,才将序列化模式切换为 xlang=true(或等效选项)。
Rust
use fory::{Error, Fory};
use 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 bytes = fory.serialize(&Person { name: "Alice".into(), age: 30 })?;
let decoded: Person = fory.deserialize(&bytes)?;
assert_eq!(decoded.age, 30);
Ok(())
}
Python
python -m pip install --upgrade pip
pip install pyfory==0.13.0
from dataclasses import dataclass
import pyfory
@dataclass
class Person:
name: str
age: pyfory.int32
fory = pyfory.Fory()
fory.register_type(Person)
payload = fory.serialize(Person(name="Alice", age=30))
decoded = fory.deserialize(payload)
print(decoded.name, decoded.age)
Java
import org.apache.fory.*;
import org.apache.fory.config.*;
public class QuickStart {
public static class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
Fory fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
.build();
fory.register(Person.class);
byte[] bytes = fory.serialize(new Person("Alice", 30));
Person result = (Person) fory.deserialize(bytes);
System.out.println(result.name + " " + result.age);
}
}
Scala
import org.apache.fory.Fory
import org.apache.fory.config.Language
import org.apache.fory.serializer.scala.ScalaSerializers
case class Person(name: String, age: Int)
object Example {
def main(args: Array[String]): Unit = {
val fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
.build()
ScalaSerializers.registerSerializers(fory)
fory.register(classOf[Person])
val bytes = fory.serialize(Person("Alice", 30))
val result = fory.deserialize(bytes).asInstanceOf[Person]
println(s"${result.name} ${result.age}")
}
}
Kotlin
import org.apache.fory.Fory
import org.apache.fory.config.Language
import org.apache.fory.serializer.kotlin.KotlinSerializers
data class Person(val name: String, val age: Int)
fun main() {
val fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
.build()
KotlinSerializers.registerSerializers(fory)
fory.register(Person::class.java)
val bytes = fory.serialize(Person("Alice", 30))
val result = fory.deserialize(bytes) as Person
println("${result.name} ${result.age}")
}
Golang
package main
import (
"fmt"
forygo "github.com/apache/fory/go/fory"
)
type Person struct {
Name string
Age int32
}
func main() {
fory := forygo.NewFory(true)
fory.Register(Person{}, 1)
payload, _ := fory.Marshal(Person{Name: "Alice", Age: 30})
var decoded Person
fory.Unmarshal(payload, &decoded)
fmt.Println(decoded.Name, decoded.Age)
}
JavaScript
import Fory, { Type } from "@apache-fory/fory";
import hps from "@apache-fory/hps";
const description = Type.object("example.Person", {
name: Type.string(),
age: Type.int32(),
});
const fory = new Fory({ hps });
const { serialize, deserialize } = fory.registerSerializer(description);
const payload = serialize({ name: "Alice", age: 30 });
const decoded = deserialize(payload);
console.log(decoded.name, decoded.age);
功能特性 ✨
- feat(java): 为 graalvm 支持 object stream 序列化 @chaokunyang,github.com/apache/fory…
- refactor(java): 将抽象集合/映射序列化器重命名为 Map/ListLikeSerializer,by @chaokunyang,github.com/apache/fory…
- feat(memory): 新增可定制的 MemoryAllocator interface,by @adriacabeza,github.com/apache/fory…
- feat: 串联 wheel test/build 和 release workflows,by @esafak,github.com/apache/fory…
- feat(python): 为 pyfory 将默认语言设为 python,by @chaokunyang,github.com/apache/fory…
- feat(python): 为 python 新增 register api,by @chaokunyang,github.com/apache/fory…
- feat(python): 为 python 提供 meta compression,by @chaokunyang,github.com/apache/fory…
- feat(python): 为 python 提供 type meta encoding,by @chaokunyang,github.com/apache/fory…
- feat(CI): Cache npm,新增 node 24 与 lock file,by @esafak,github.com/apache/fory…
- feat(Rust): 实现 Type Compatible,by @urlyy,github.com/apache/fory…
- feat(Rust): 在 MetaFieldType se/de 中支持 Option,by @urlyy,github.com/apache/fory…
- feat(rust): 在 compatible 模式反序列化时支持 skipping fields bytes,by @urlyy,github.com/apache/fory…
- feat(go): 为 meta share 新增 type meta encoding,by @junjiexh,github.com/apache/fory…
- feat(Rust): 反序列化时支持 T 与
Option<T>的自动转换,by @urlyy,github.com/apache/fory… - feat(java): bean encoder 实现的 interfaces 支持
@Ignore,by @stevenschlansker,github.com/apache/fory… - refactor(java): 重构 fory java exception hierarchical structure,by @chaokunyang,github.com/apache/fory…
- feat(Go): 为 fory-go serialization 实现 ahead of time codegen,by @ThisingL,github.com/apache/fory…
- feat(java): 支持限制 deserialization depth,by @chaokunyang,github.com/apache/fory…
- feat(rust): 新增 fory rust benchmark,by @chaokunyang,github.com/apache/fory…
- perf(rust): 优化 rust deserialize 性能,by @chaokunyang,github.com/apache/fory…
- feat(rust): 新增 rust profiler for serialization,by @chaokunyang,github.com/apache/fory…
- refactor(go): 将 FieldInfo 重命名为 FieldDef 以避免 name collision,by @junjiexh,github.com/apache/fory…
- feat(python): 为 pyfory compatible serialization 提供 meta share mode,by @chaokunyang,github.com/apache/fory…
- feat(java/python): 对齐 java 与 python 的 compatible mode serialization,by @chaokunyang,github.com/apache/fory…
- feat(java/python): 支持 enum xlang serialization,by @chaokunyang,github.com/apache/fory…
- feat(Rust): 支持与 java 对齐的 basic type se/de,by @urlyy,github.com/apache/fory…
- perf(python/java): 修复并优化 cross-language meta-share mode,by @pandalee99,github.com/apache/fory…
- feat(go): 对齐跨语言 primitive arrays 的 type serialization,by @pandalee99,github.com/apache/fory…
- feat(java): 支持 xlang 模式的 codegen,by @chaokunyang,github.com/apache/fory…
- feat(java): 使用 SIMD 的 primitive array compression,by @adriacabeza,github.com/apache/fory…
- refactor