Pengkodean biner cepat memungkinkan untuk menggambarkan model domain apa pun, objek bisnis, struktur data yang kompleks, permintaan & respons klien/server dan menghasilkan kode asli untuk berbagai bahasa dan platform pemrograman yang berbeda.
Dokumentasi penyandian biner cepat
Unduhan penyandian biner cepat
Spesifikasi penyandian biner cepat
Perbandingan kinerja dengan protokol lain dapat ditemukan di sini:
| Protokol | Ukuran pesan | Waktu serialisasi | Waktu deserialisasi |
|---|---|---|---|
| Cap'n'proto | 208 byte | 558 ns | 359 ns |
| Fastbinaryencoding | 234 byte | 66 ns | 82 ns |
| Flatbuffer | 280 byte | 830 ns | 290 ns |
| Protobuf | 120 byte | 628 ns | 759 ns |
| Json | 301 byte | 740 ns | 500 ns |
Alur kerja penggunaan khas adalah sebagai berikut:
Contoh Proyek:
Opsional:
sudo apt-get install -y binutils-dev uuid-dev flex bisonbrew install flex bisonchoco install winflexbison3pip3 install gilgit clone https://github.com/chronoxor/FastBinaryEncoding.git
cd FastBinaryEncoding
gil update cd build
./unix.sh cd build
./unix.sh cd build
unix.bat cd build
unix.bat cd build
mingw.bat cd build
vs.batUntuk menggunakan penyandian biner cepat, Anda harus memberikan model domain (alias objek bisnis). Model domain adalah satu set enum, bendera dan struktur yang berhubungan satu sama lain dan mungkin dikumpulkan dalam beberapa hierarki.
Spesifikasi Format Encoding Fast Binary (FBE)
Ada model domain sampel yang menjelaskan hubungan akun-balance-order dari beberapa platform perdagangan abstrak:
// Package declaration
package proto
// Domain declaration
domain com.chronoxor
// Order side declaration
enum OrderSide : byte
{
buy;
sell;
}
// Order type declaration
enum OrderType : byte
{
market;
limit;
stop;
}
// Order declaration
struct Order
{
[key] int32 uid;
string symbol;
OrderSide side;
OrderType type;
double price = 0.0;
double volume = 0.0;
}
// Account balance declaration
struct Balance
{
[key] string currency;
double amount = 0.0;
}
// Account state declaration
flags State : byte
{
unknown = 0x00;
invalid = 0x01;
initialized = 0x02;
calculated = 0x04;
broken = 0x08;
good = initialized | calculated;
bad = unknown | invalid | broken;
}
// Account declaration
struct Account
{
[key] int32 uid;
string name;
State state = State.initialized | State.bad;
Balance wallet;
Balance? asset;
Order[] orders;
}Langkah selanjutnya adalah kompilasi model domain menggunakan kompiler 'FBEC' yang akan membuat kode yang dihasilkan untuk bahasa pemrograman yang diperlukan.
Perintah berikut akan membuat kode C ++ yang dihasilkan:
fbec --c++ --input=proto.fbe --output=.Semua opsi yang mungkin untuk kompiler 'FBEC' adalah sebagai berikut:
Usage: fbec [options]
Options:
--version show program ' s version number and exit
-h, --help show this help message and exit
-h HELP, --help=HELP Show help
-i INPUT, --input=INPUT
Input path
-o OUTPUT, --output=OUTPUT
Output path
-q, --quiet Launch in quiet mode. No progress will be shown!
-n INDENT, --indent=INDENT
Format indent. Default: 0
-t, --tabs Format with tabs. Default: off
--cpp Generate C++ code
--cpp-logging Generate C++ logging code
--csharp Generate C# code
--go Generate Go code
--java Generate Java code
--javascript Generate JavaScript code
--kotlin Generate Kotlin code
--python Generate Python code
--ruby Generate Ruby code
--swift Generate Swift code
--final Generate Final serialization code
--json Generate JSON serialization code
--proto Generate Sender/Receiver protocol codeModel domain yang dihasilkan diwakili dengan kode sumber untuk bahasa tertentu. Tambahkan saja ke proyek Anda dan bangun. Ada beberapa masalah dan dependensi yang harus disebutkan:
<fmt/format.h> dan <fmt/ostream.h> ;go get github.com/stretchr/testify );go get github.com/json-iterator/go );go get github.com/shopspring/decimal );go get github.com/google/uuid );gem install json
gem install uuidtoolsFast Binary Encoding (FBE) adalah format biner yang cepat dan kompak untuk mewakili model domain tunggal dalam berbagai bahasa dan platform pemrograman. Format FBE juga memecahkan masalah versi protokol.
Ikuti langkah -langkah di bawah ini untuk membuat serialisasi objek domain apa pun:
Ikuti langkah -langkah di bawah ini untuk menghapus objek domain apa pun:
Berikut adalah exmple dari serialisasi FBE dalam bahasa C ++:
# include " ../proto/proto_models.h "
# include < iostream >
int main ( int argc, char ** argv)
{
// Create a new account with some orders
proto::Account account = { 1 , " Test " , proto::State::good, { " USD " , 1000.0 }, std::make_optional<proto::Balance>({ " EUR " , 100.0 }), {} };
account. orders . emplace_back ( 1 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::market, 1.23456 , 1000.0 );
account. orders . emplace_back ( 2 , " EURUSD " , proto::OrderSide::sell, proto::OrderType::limit, 1.0 , 100.0 );
account. orders . emplace_back ( 3 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::stop, 1.5 , 10.0 );
// Serialize the account to the FBE stream
FBE::proto::AccountModel<FBE::WriteBuffer> writer;
writer. serialize (account);
assert (writer. verify ());
// Show the serialized FBE size
std::cout << " FBE size: " << writer. buffer (). size () << std::endl;
// Deserialize the account from the FBE stream
FBE::proto::AccountModel<FBE::ReadBuffer> reader;
reader. attach (writer. buffer ());
assert (reader. verify ());
reader. deserialize (account);
// Show account content
std::cout << std::endl;
std::cout << account;
return 0 ;
}Output adalah sebagai berikut:
FBE size: 252
Account(
uid=1,
name="Test",
state=initialized|calculated|good,
wallet=Balance(currency="USD",amount=1000),
asset=Balance(currency="EUR",amount=100),
orders=[3][
Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000),
Order(uid=2,symbol="EURUSD",side=sell,type=limit,price=1,volume=100),
Order(uid=3,symbol="EURUSD",side=buy,type=stop,price=1.5,volume=10)
]
)
Dimungkinkan untuk mencapai lebih banyak kecepatan serialisasi jika protokol Anda cukup matang sehingga Anda dapat memperbaiki versi final dan menonaktifkan versi yang membutuhkan ukuran dan waktu ekstra untuk diproses.
| Protokol | Ukuran pesan | Waktu serialisasi | Waktu deserialisasi | Verifikasi waktu |
|---|---|---|---|---|
| Fbe | 252 byte | 88 ns | 98 ns | 33 ns |
| Final fbe | 152 byte | 57 ns | 81 ns | 28 ns |
Model domain akhir dapat dikompilasi dengan -bendera final. Karena hasilnya, model akhir tambahan akan tersedia untuk serialisasi.
Ikuti langkah -langkah di bawah ini untuk membuat serialisasi objek domain apa pun dalam format akhir:
Ikuti langkah -langkah di bawah ini untuk menghapus objek domain apa pun:
Berikut ini adalah exmple dari serialisasi akhir FBE dalam bahasa C ++:
# include " ../proto/proto_models.h "
# include < iostream >
int main ( int argc, char ** argv)
{
// Create a new account with some orders
proto::Account account = { 1 , " Test " , proto::State::good, { " USD " , 1000.0 }, std::make_optional<proto::Balance>({ " EUR " , 100.0 }), {} };
account. orders . emplace_back ( 1 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::market, 1.23456 , 1000.0 );
account. orders . emplace_back ( 2 , " EURUSD " , proto::OrderSide::sell, proto::OrderType::limit, 1.0 , 100.0 );
account. orders . emplace_back ( 3 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::stop, 1.5 , 10.0 );
// Serialize the account to the FBE stream
FBE::proto::AccountFinalModel<FBE::WriteBuffer> writer;
writer. serialize (account);
assert (writer. verify ());
// Show the serialized FBE size
std::cout << " FBE final size: " << writer. buffer (). size () << std::endl;
// Deserialize the account from the FBE stream
FBE::proto::AccountFinalModel<FBE::ReadBuffer> reader;
reader. attach (writer. buffer ());
assert (reader. verify ());
reader. deserialize (account);
// Show account content
std::cout << std::endl;
std::cout << account;
return 0 ;
}Output adalah sebagai berikut:
FBE final size: 152
Account(
uid=1,
name="Test",
state=initialized|calculated|good,
wallet=Balance(currency="USD",amount=1000),
asset=Balance(currency="EUR",amount=100),
orders=[3][
Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000),
Order(uid=2,symbol="EURUSD",side=sell,type=limit,price=1,volume=100),
Order(uid=3,symbol="EURUSD",side=buy,type=stop,price=1.5,volume=10)
]
)
Jika model domain dikompilasi dengan -bendera -JSON, maka kode serialisasi JSON akan dihasilkan di semua objek domain. Sebagai hasilnya, setiap objek domain dapat diserialisasi/deserialisasi ke dalam/dari format JSON.
Harap dicatat bahwa beberapa bahasa pemrograman memiliki dukungan JSON asli (JavaScript, Python). Bahasa lain membutuhkan perpustakaan pihak ketiga untuk mendapatkan pekerjaan dengan JSON:
Berikut ini adalah exmple dari serialisasi JSON dalam bahasa C ++:
# include " ../proto/proto.h "
# include < iostream >
int main ( int argc, char ** argv)
{
// Create a new account with some orders
proto::Account account = { 1 , " Test " , proto::State::good, { " USD " , 1000.0 }, std::make_optional<proto::Balance>({ " EUR " , 100.0 }), {} };
account. orders . emplace_back ( 1 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::market, 1.23456 , 1000.0 );
account. orders . emplace_back ( 2 , " EURUSD " , proto::OrderSide::sell, proto::OrderType::limit, 1.0 , 100.0 );
account. orders . emplace_back ( 3 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::stop, 1.5 , 10.0 );
// Serialize the account to the JSON stream
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
FBE::JSON::to_json (writer, account);
// Show the serialized JSON and its size
std::cout << " JSON: " << buffer. GetString () << std::endl;
std::cout << " JSON size: " << buffer. GetSize () << std::endl;
// Parse the JSON document
rapidjson::Document json;
json. Parse (buffer. GetString ());
// Deserialize the account from the JSON stream
FBE::JSON::from_json (json, account);
// Show account content
std::cout << std::endl;
std::cout << account;
return 0 ;
}Output adalah sebagai berikut:
JSON: {
"uid":1,
"name":
"Test",
"state":6,
"wallet":{"currency":"USD","amount":1000.0},
"asset":{"currency":"EUR","amount":100.0},
"orders":[
{"uid":1,"symbol":"EURUSD","side":0,"type":0,"price":1.23456,"volume":1000.0},
{"uid":2,"symbol":"EURUSD","side":1,"type":1,"price":1.0,"volume":100.0},
{"uid":3,"symbol":"EURUSD","side":0,"type":2,"price":1.5,"volume":10.0}
]
}
JSON size: 353
Account(
uid=1,
name="Test",
state=initialized|calculated|good,
wallet=Balance(currency="USD",amount=1000),
asset=Balance(currency="EUR",amount=100),
orders=[3][
Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000),
Order(uid=2,symbol="EURUSD",side=sell,type=limit,price=1,volume=100),
Order(uid=3,symbol="EURUSD",side=buy,type=stop,price=1.5,volume=10)
]
)
Paket dinyatakan dengan nama paket dan struct offset (opsional). Offset akan ditambahkan ke jenis struktur bertambah jika tidak disediakan secara eksplisit.
Berikut adalah contoh deklarasi paket sederhana:
// Package declaration. Offset is 0.
package proto
// Struct type number is 1 (proto offset 0 + 1)
struct Struct1
{
...
}
// Struct type number is 2 (proto offset 0 + 2)
struct Struct2
{
...
}Satu paket dapat diimpor ke yang lain dan semua enum, bendera, dan struct dapat digunakan kembali dalam paket saat ini. Paket Offset digunakan di sini untuk menghindari persimpangan jenis struct:
// Package declaration. Offset is 10.
package protoex offset 10
// Package import
import proto
// Struct type number is 11 (protoex offset 10 + 1)
struct Struct11
{
// Struct1 is reused form the imported package
proto.Struct1 s1;
...
}
// Struct type number is 12 (protoex offset 10 + 2)
struct Struct12
{
...
}Beberapa impor paket juga dimungkinkan:
// Package declaration. Offset is 100.
package test offset 100
// Package import
import proto
import protoex
...Impor paket diimplementasikan menggunakan:
Beberapa pengarsipan struct (satu atau banyak) dapat ditandai dengan atribut '[Key]'. Karena hasil yang sesuai, perbandingan operator akan dihasilkan yang memungkinkan untuk membandingkan dua contoh struct (kesetaraan, pemesanan, hashing) dengan bidang yang ditandai. Kemampuan ini memungkinkan untuk menggunakan struct sebagai kunci dalam peta asosiatif dan wadah hash.
Contoh di bawah ini menunjukkan penggunaan atribut '[Key]':
struct MyKeyStruct
{
[key] int32 uid;
[key] stirng login;
string name;
string address;
}Setelah pembuatan kode untuk bahasa C ++, kelas yang sebanding berikut akan dihasilkan:
struct MyKeyStruct
{
int32_t uid;
::sample::stirng login;
std::string name;
std::string address;
...
bool operator ==( const MyKeyStruct& other) const noexcept
{
return (
(uid == other. uid )
&& (login == other. login )
);
}
bool operator !=( const MyKeyStruct& other) const noexcept { return ! operator ==(other); }
bool operator <( const MyKeyStruct& other) const noexcept
{
if (uid < other. uid )
return true ;
if (other. uid < uid)
return false ;
if (login < other. login )
return true ;
if (other. login < login)
return false ;
return false ;
}
bool operator <=( const MyKeyStruct& other) const noexcept { return operator <(other) || operator ==(other); }
bool operator >( const MyKeyStruct& other) const noexcept { return ! operator <=(other); }
bool operator >=( const MyKeyStruct& other) const noexcept { return ! operator <(other); }
...
};Jenis jenis struct meningkat secara otomatis sampai Anda menyediakannya secara manual. Ada dua kemungkinan:
Contoh di bawah ini menunjukkan ide:
// Package declaration. Offset is 0.
package proto
// Struct type number is 1 (implicit declared)
struct Struct1
{
...
}
// Struct type number is 2 (implicit declared)
struct Struct2
{
...
}
// Struct type number is 10 (explicit declared, shifted to 10)
struct Struct10(+10)
{
...
}
// Struct type number is 11 (implicit declared)
struct Struct11
{
...
}
// Struct type number is 100 (explicit declared, forced to 100)
struct Struct100(100)
{
...
}
// Struct type number is 12 (implicit declared)
struct Struct12
{
...
}Struct dapat diwarisi dari struct lain. Dalam hal ini semua bidang dari struct dasar akan hadir pada anak.
package proto
// Struct type number is 1
struct StructBase
{
bool f1;
int8 f2;
}
// Struct type number is 2
struct StructChild : StructBase
{
// bool f1 - will be inherited from StructBase
// int8 f2 - will be inherited from StructBase
int16 f3;
int32 f4;
}Juga dimungkinkan untuk menggunakan kembali nomor tipe struct dasar pada anak satu menggunakan '= base' operator. Ini berguna ketika Anda memperluas struct dari paket impor pihak ketiga:
// Package declaration. Offset is 10.
package protoex offset 10
// Package import
import proto
// Struct type number is 1
struct StructChild(base) : proto.StructBase
{
// bool f1 - will be inherited from proto.StructBase
// int8 f2 - will be inherited from proto.StructBase
int16 f3;
int32 f4;
}Versi sederhana dengan penyandian biner cepat.
Asumsikan Anda memiliki protokol asli:
package proto
enum MyEnum
{
value1;
value2;
}
flags MyFlags
{
none = 0x00;
flag1 = 0x01;
flag2 = 0x02;
flag3 = 0x04;
}
struct MyStruct
{
bool field1;
byte field2;
char field3;
}Anda perlu memperpanjangnya dengan nilai enum, bendera, dan struct baru. Cukup tambahkan nilai yang diperlukan ke akhir deklarasi yang sesuai:
package proto
enum MyEnum
{
value1;
value2;
value3; // New value
value4; // New value
}
flags MyFlags
{
none = 0x00;
flag1 = 0x01;
flag2 = 0x02;
flag3 = 0x04;
flag4 = 0x08; // New value
flag5 = 0x10; // New value
}
struct MyStruct
{
bool field1;
byte field2;
char field3;
int32 field4; // New field (default value is 0)
int64 field5 = 123456; // New field (default value is 123456)
}Sekarang Anda dapat membuat serialisasi dan deserialize struct dalam kombinasi yang berbeda:
Jika Anda tidak dapat memodifikasi beberapa protokol pihak ketiga, Anda masih dapat memiliki solusi untuk memperpanjangnya. Cukup buat protokol baru dan impor pihak ketiga ke dalamnya. Kemudian rentangkan struct dengan warisan:
package protoex
import proto
struct MyStructEx(base) : proto.MyStruct
{
int32 field4; // New field (default value is 0)
int64 field5 = 123456; // New field (default value is 123456)
}Jika model domain yang dikompilasi dengan -Sender Flag, maka Kode Protokol Pengirim/Penerima akan dihasilkan.
Antarmuka pengirim berisi metode 'Send (struct)' untuk semua struct model domain. Juga memiliki metode abstrak 'Onsend (Data, Size)' yang harus diimplementasikan untuk mengirim data serial ke soket, pipa, dll.
Antarmuka penerima berisi penangan 'OnReceive (struct)' untuk semua struct model domain. Juga memiliki metode 'onreceive (tipe, data, ukuran) publik yang harus digunakan untuk memberi makan penerima dengan data yang diterima dari soket, pipa, dll.
Berikut adalah exmple menggunakan protokol komunikasi pengirim/penerima dalam bahasa C ++:
# include " ../proto/proto_protocol.h "
# include < iostream >
class MySender : public FBE ::proto::Sender<FBE::WriteBuffer>
{
protected:
size_t onSend ( const void * data, size_t size) override
{
// Send nothing...
return 0 ;
}
void onSendLog ( const std::string& message) const override
{
std::cout << " onSend: " << message << std::endl;
}
};
class MyReceiver : public FBE ::proto::Receiver<FBE::WriteBuffer>
{
protected:
void onReceive ( const proto::Order& value) override {}
void onReceive ( const proto::Balance& value) override {}
void onReceive ( const proto::Account& value) override {}
void onReceiveLog ( const std::string& message) const override
{
std::cout << " onReceive: " << message << std::endl;
}
};
int main ( int argc, char ** argv)
{
MySender sender;
// Enable logging
sender. logging ( true );
// Create and send a new order
proto::Order order = { 1 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::market, 1.23456 , 1000.0 };
sender. send (order);
// Create and send a new balance wallet
proto::Balance balance = { " USD " , 1000.0 };
sender. send (balance);
// Create and send a new account with some orders
proto::Account account = { 1 , " Test " , proto::State::good, { " USD " , 1000.0 }, std::make_optional<proto::Balance>({ " EUR " , 100.0 }), {} };
account. orders . emplace_back ( 1 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::market, 1.23456 , 1000.0 );
account. orders . emplace_back ( 2 , " EURUSD " , proto::OrderSide::sell, proto::OrderType::limit, 1.0 , 100.0 );
account. orders . emplace_back ( 3 , " EURUSD " , proto::OrderSide::buy, proto::OrderType::stop, 1.5 , 10.0 );
sender. send (account);
MyReceiver receiver;
// Enable logging
receiver. logging ( true );
// Receive all data from the sender
receiver. receive (sender. buffer (). data (), sender. buffer (). size ());
return 0 ;
}Output adalah sebagai berikut:
onSend: Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000)
onSend: Balance(currency="USD",amount=1000)
onSend: Account(uid=1,name="Test",state=initialized|calculated|good,wallet=Balance(currency="USD",amount=1000),asset=Balance(currency="EUR",amount=100),orders=[3][Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000),Order(uid=2,symbol="EURUSD",side=sell,type=limit,price=1,volume=100),Order(uid=3,symbol="EURUSD",side=buy,type=stop,price=1.5,volume=10)])
onReceive: Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000)
onReceive: Balance(currency="USD",amount=1000)
onReceive: Account(uid=1,name="Test",state=initialized|calculated|good,wallet=Balance(currency="USD",amount=1000),asset=Balance(currency="EUR",amount=100),orders=[3][Order(uid=1,symbol="EURUSD",side=buy,type=market,price=1.23456,volume=1000),Order(uid=2,symbol="EURUSD",side=sell,type=limit,price=1,volume=100),Order(uid=3,symbol="EURUSD",side=buy,type=stop,price=1.5,volume=10)])
Semua tolok ukur menggunakan model domain yang sama untuk membuat akun tunggal dengan tiga pesanan:
Account account = { 1 , " Test " , State::good, { " USD " , 1000.0 }, std::make_optional<Balance>({ " EUR " , 100.0 }), {} };
account.orders.emplace_back( 1 , " EURUSD " , OrderSide::buy, OrderType::market, 1.23456 , 1000.0 );
account.orders.emplace_back( 2 , " EURUSD " , OrderSide::sell, OrderType::limit, 1.0 , 100.0 );
account.orders.emplace_back( 3 , " EURUSD " , OrderSide::buy, OrderType::stop, 1.5 , 10.0 );Serialisasi Benchmark C ++ Code:
BENCHMARK_FIXTURE (SerializationFixture, " Serialize " )
{
// Reset FBE stream
writer. reset ();
// Serialize the account to the FBE stream
writer. serialize (account);
}Hasil Benchmark Serialisasi:
| Bahasa & Platform | Ukuran pesan | Tingkat serialisasi | Waktu serialisasi |
|---|---|---|---|
| C ++ Win64 | 252 byte | 10 416 667 OPS/S | 96 ns |
| C ++ Win64 (final) | 152 byte | 16 129 032 OPS/S | 62 ns |
| C ++ Win64 (JSON) | 353 byte | 926 784 OPS/S. | 1 079 ns |
| C# win64 | 252 byte | 1 432 665 OPS/S | 698 ns |
| C# win64 (final) | 152 byte | 1 597 444 OPS/S | 626 ns |
| C# Win64 (JSON) | 341 byte | 434 783 OPS/S. | 2 300 ns |
| Pergi win64 | 252 byte | 2 739 726 OPS/S | 365 ns |
| Go win64 (final) | 152 byte | 2 949 852 OPS/S | 339 ns |
| Go Win64 (JSON) | 341 byte | 258 732 OPS/S. | 3 865 ns |
| Java Win64 | 252 byte | 4 247 162 OPS/S | 236 ns |
| Java Win64 (final) | 152 byte | 4 883 205 OPS/S | 205 ns |
| Java Win64 (JSON) | 353 byte | 213 983 OPS/S. | 4 673 ns |
| JavaScript Win64 | 252 byte | 93 416 OPS/S. | 10 705 ns |
| JavaScript Win64 (final) | 152 byte | 112 665 OPS/S. | 8 876 ns |
| Javascript Win64 (JSON) | 341 byte | 217 637 OPS/S. | 4 595 ns |
| Kotlin Win64 | 252 byte | 3 546 694 OPS/S | 282 ns |
| Kotlin Win64 (final) | 152 byte | 4 096 406 OPS/S | 244 ns |
| Kotlin Win64 (JSON) | 353 byte | 185 788 OPS/S. | 5 382 ns |
| Python Win64 | 252 byte | 9 434 OPS/S. | 105 999 ns |
| Python Win64 (final) | 152 byte | 11 635 OPS/S. | 85 945 ns |
| Python Win64 (JSON) | 324 byte | 61 737 OPS/S. | 16 198 ns |
| Ruby Win64 | 252 byte | 23 013 OPS/S. | 43 453 ns |
| Ruby Win64 (final) | 152 byte | 33 361 OPS/S. | 29 975 ns |
| Ruby Win64 (JSON) | 353 byte | 50 842 OPS/S. | 19 669 ns |
| SWIFT MacOS | 252 byte | 74 002 OPS/S. | 13 513 ns |
| Swift MacOS (final) | 152 byte | 100 755 OPS/S. | 9 925 ns |
| Swift MacOS (JSON) | 353 byte | 18 534 OPS/S. | 53 953 ns |
Kode Benchmark C ++ Deserialization:
BENCHMARK_FIXTURE (DeserializationFixture, " Deserialize " )
{
// Deserialize the account from the FBE stream
reader. deserialize (deserialized);
}Hasil Benchmark Deserialisasi:
| Bahasa & Platform | Ukuran pesan | Tingkat deserialisasi | Waktu deserialisasi |
|---|---|---|---|
| C ++ Win64 | 252 byte | 9 523 810 OPS/S | 105 ns |
| C ++ Win64 (final) | 152 byte | 10 989 011 OPS/S | 91 ns |
| C ++ Win64 (JSON) | 353 byte | 1 375 516 OPS/S | 727 ns |
| C# win64 | 252 byte | 1 014 199 OPS/S | 986 ns |
| C# win64 (final) | 152 byte | 1 607 717 OPS/S | 622 ns |
| C# Win64 (JSON) | 341 byte | 258 532 OPS/S. | 3 868 ns |
| Pergi win64 | 252 byte | 1 510 574 OPS/S | 662 ns |
| Go win64 (final) | 152 byte | 1 540 832 OPS/S | 649 ns |
| Go Win64 (JSON) | 341 byte | 251 825 OPS/S. | 3 971 ns |
| Java Win64 | 252 byte | 2 688 084 OPS/S | 372 ns |
| Java Win64 (final) | 152 byte | 3 036 020 OPS/S | 329 ns |
| Java Win64 (JSON) | 353 byte | 308 675 OPS/S. | 3 240 ns |
| JavaScript Win64 | 252 byte | 133 892 OPS/S. | 7 469 ns |
| JavaScript Win64 (final) | 152 byte | 292 273 OPS/S. | 3 422 ns |
| Javascript Win64 (JSON) | 341 byte | 289 417 OPS/S. | 3 455 ns |
| Kotlin Win64 | 252 byte | 2 280 923 OPS/S | 438 ns |
| Kotlin Win64 (final) | 152 byte | 2 652 728 OPS/S | 277 ns |
| Kotlin Win64 (JSON) | 353 byte | 250 524 OPS/S. | 3 992 ns |
| Python Win64 | 252 byte | 8 305 OPS/S. | 120 411 ns |
| Python Win64 (final) | 152 byte | 11 661 OPS/S. | 85 758 ns |
| Python Win64 (JSON) | 324 byte | 48 859 OPS/S. | 20 467 ns |
| Ruby Win64 | 252 byte | 24 351 OPS/S. | 41 066 ns |
| Ruby Win64 (final) | 152 byte | 33 555 OPS/S. | 29 802 ns |
| Ruby Win64 (JSON) | 353 byte | 42 860 OPS/S. | 23 331 ns |
| SWIFT MacOS | 252 byte | 86 288 OPS/S. | 11 589 ns |
| Swift MacOS (final) | 152 byte | 10 3519 OPS/S. | 9 660 ns |
| Swift MacOS (JSON) | 353 byte | 17 077 OPS/S. | 58 558 ns |
Verifikasi Benchmark C ++ Code:
BENCHMARK_FIXTURE (VerifyFixture, " Verify " )
{
// Verify the account
model. verify ();
}Verifikasi hasil benchmark:
| Bahasa & Platform | Ukuran pesan | Verifikasi tarif | Verifikasi waktu |
|---|---|---|---|
| C ++ Win64 | 252 byte | 31 250 000 ops/s | 32 ns |
| C ++ Win64 (final) | 152 byte | 35 714 286 OPS/S | 28 ns |
| C# win64 | 252 byte | 4 504 505 OPS/S | 222 ns |
| C# win64 (final) | 152 byte | 8 064 516 OPS/S | 124 ns |
| Pergi win64 | 252 byte | 8 474 576 OPS/S | 118 ns |
| Go win64 (final) | 152 byte | 9 090 909 OPS/S | 110 ns |
| Java Win64 | 252 byte | 11 790 374 OPS/S | 85 ns |
| Java Win64 (final) | 152 byte | 16 205 533 OPS/S | 62 ns |
| JavaScript Win64 | 252 byte | 1 105 627 OPS/S | 905 ns |
| JavaScript Win64 (final) | 152 byte | 5 700 408 OPS/S | 175 ns |
| Kotlin Win64 | 252 byte | 8 625 935 OPS/S | 116 ns |
| Kotlin Win64 (final) | 152 byte | 13 373 757 OPS/S | 75 ns |
| Python Win64 | 252 byte | 20 825 OPS/S. | 48 019 ns |
| Python Win64 (final) | 152 byte | 23 590 OPS/S. | 42 391 ns |
| Ruby Win64 | 252 byte | 57 201 OPS/S. | 17 482 ns |
| Ruby Win64 (final) | 152 byte | 74 262 OPS/S. | 13 466 ns |
| SWIFT MacOS | 252 byte | 164 446 OPS/S. | 6 081 ns |
| Swift MacOS (final) | 152 byte | 228 154 OPS/S. | 4 383 ns |