Skip to content

Instantly share code, notes, and snippets.

@andrewmd5
Last active June 19, 2025 13:55
Show Gist options
  • Save andrewmd5/aaac0436befdcd5b12c555a8382a3bf9 to your computer and use it in GitHub Desktop.
Save andrewmd5/aaac0436befdcd5b12c555a8382a3bf9 to your computer and use it in GitHub Desktop.
Bebop C examples
Bebop Jazz Library Performance Benchmark
========================================
Iterations per test: 10000
Warming up...
Warmup complete.
Predicted size: 307 bytes, Actual size: 307 bytes
=== Optimized Encoding Benchmark ===
Iterations: 10000
Encoded size: 307 bytes
Encode time: 1.114 ms (0.111 µs per op)
Decode time: 0.000 ms (0.000 µs per op)
Throughput: 2628.17 MB/s
Operations per second: 8976661
=== Optimized Decoding Benchmark ===
Iterations: 10000
Encoded size: 307 bytes
Encode time: 0.000 ms (0.000 µs per op)
Decode time: 1.029 ms (0.103 µs per op)
Throughput: 2845.27 MB/s
Operations per second: 9718173
=== Optimized Roundtrip Benchmark ===
Iterations: 10000
Encoded size: 307 bytes
Encode time: 0.852 ms (0.085 µs per op)
Decode time: 0.852 ms (0.085 µs per op)
Throughput: 3436.36 MB/s
Operations per second: 5868545
=== Error Handling Benchmark ===
Error handling rate: 4449 errors/sec
Correctly handled: 1000/1000 malformed packets
Average time per error: 224.752 µs
=== Performance Summary ===
Encode rate: 8976661 ops/sec (2628.17 MB/s)
Decode rate: 9718173 ops/sec (2845.27 MB/s)
Roundtrip rate: 5868545 ops/sec (3436.36 MB/s)
Data size: 307 bytes per library
enum Instrument {
Sax = 0;
Trumpet = 1;
Clarinet = 2;
}
/* test */
@opcode("JAZZ")
struct Musician {
/* a name */
string name;
/* an instrument */
Instrument plays;
}
message Song {
1 -> string title;
2 -> uint16 year;
3 -> Musician[] performers;
}
mut struct Library {
map[guid, Song] songs;
}
struct AudioData {
float32[] samples;
}
/* Auto-generated by bebop compiler */
#include "jazz.h"
#include <string.h>
// #region Function Implementations
bebop_result_t audio_data_encode_into(const audio_data_t* record,
bebop_writer_t* writer) {
if (!record || !writer) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
result = bebop_writer_write_float32_array(writer, record->samples.data,
record->samples.length);
if (result != BEBOP_OK) return result;
return BEBOP_OK;
}
bebop_result_t audio_data_encode(const audio_data_t* record,
bebop_writer_t* writer) {
return audio_data_encode_into(record, writer);
}
bebop_result_t audio_data_decode_into(bebop_reader_t* reader,
audio_data_t* out_record) {
if (!reader || !out_record) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
uint32_t length_0;
result = bebop_reader_read_uint32(reader, &length_0);
if (result != BEBOP_OK) return result;
((bebop_float32_array_view_t*)&out_record->samples)->length = length_0;
((bebop_float32_array_view_t*)&out_record->samples)->data =
(float*)bebop_reader_position(reader);
bebop_reader_skip(reader, length_0 * sizeof(float));
return BEBOP_OK;
}
bebop_result_t audio_data_decode(bebop_reader_t* reader,
audio_data_t* out_record) {
return audio_data_decode_into(reader, out_record);
}
size_t audio_data_encoded_size(const audio_data_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t) + (record->samples.length * 4);
return byte_count;
}
size_t audio_data_max_encoded_size(const audio_data_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t) + (record->samples.length * 4);
return byte_count;
}
bebop_result_t musician_encode_into(const musician_t* record,
bebop_writer_t* writer) {
if (!record || !writer) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
result = bebop_writer_write_string_view(writer, record->name);
if (result != BEBOP_OK) return result;
result = bebop_writer_write_uint32(writer, record->plays);
if (result != BEBOP_OK) return result;
return BEBOP_OK;
}
bebop_result_t musician_encode(const musician_t* record,
bebop_writer_t* writer) {
return musician_encode_into(record, writer);
}
bebop_result_t musician_decode_into(bebop_reader_t* reader,
musician_t* out_record) {
if (!reader || !out_record) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
result = bebop_reader_read_string_view(
reader, (bebop_string_view_t*)&out_record->name);
if (result != BEBOP_OK) return result;
result = bebop_reader_read_uint32(reader, (uint32_t*)&out_record->plays);
if (result != BEBOP_OK) return result;
return BEBOP_OK;
}
bebop_result_t musician_decode(bebop_reader_t* reader, musician_t* out_record) {
return musician_decode_into(reader, out_record);
}
size_t musician_encoded_size(const musician_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t) + record->name.length;
byte_count += sizeof(uint32_t);
return byte_count;
}
size_t musician_max_encoded_size(const musician_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t) +
(record->name.length * 4); /* Max UTF-8 bytes per char */
byte_count += sizeof(uint32_t);
return byte_count;
}
bebop_result_t song_encode_into(const song_t* record, bebop_writer_t* writer) {
if (!record || !writer) return BEBOP_ERROR_NULL_POINTER;
size_t pos;
bebop_result_t result = bebop_writer_reserve_message_length(writer, &pos);
if (result != BEBOP_OK) return result;
size_t start = bebop_writer_length(writer);
if (bebop_is_some(record->title)) {
result = bebop_writer_write_byte(writer, 1);
if (result != BEBOP_OK) return result;
result =
bebop_writer_write_string_view(writer, bebop_unwrap(record->title));
if (result != BEBOP_OK) return result;
}
if (bebop_is_some(record->year)) {
result = bebop_writer_write_byte(writer, 2);
if (result != BEBOP_OK) return result;
result = bebop_writer_write_uint16(writer, bebop_unwrap(record->year));
if (result != BEBOP_OK) return result;
}
if (bebop_is_some(record->performers)) {
result = bebop_writer_write_byte(writer, 3);
if (result != BEBOP_OK) return result;
result = bebop_writer_write_uint32(
writer, (uint32_t)bebop_unwrap(record->performers).length);
if (result != BEBOP_OK) return result;
for (size_t i0 = 0; i0 < bebop_unwrap(record->performers).length; i0++) {
result = musician_encode_into(&bebop_unwrap(record->performers).data[i0],
writer);
if (result != BEBOP_OK) return result;
}
}
result = bebop_writer_write_byte(writer, 0);
if (result != BEBOP_OK) return result;
size_t end = bebop_writer_length(writer);
return bebop_writer_fill_message_length(writer, pos, (uint32_t)(end - start));
}
bebop_result_t song_encode(const song_t* record, bebop_writer_t* writer) {
return song_encode_into(record, writer);
}
bebop_result_t song_decode_into(bebop_reader_t* reader, song_t* out_record) {
if (!reader || !out_record) return BEBOP_ERROR_NULL_POINTER;
memset(out_record, 0, sizeof(*out_record));
uint32_t length;
bebop_result_t result = bebop_reader_read_length_prefix(reader, &length);
if (result != BEBOP_OK) return result;
const uint8_t* end = bebop_reader_position(reader) + length;
while (bebop_reader_position(reader) < end) {
uint8_t field_id;
result = bebop_reader_read_byte(reader, &field_id);
if (result != BEBOP_OK) return result;
switch (field_id) {
case 0:
return BEBOP_OK;
case 1:
out_record->title.has_value = true;
result =
bebop_reader_read_string_view(reader, &out_record->title.value);
if (result != BEBOP_OK) return result;
break;
case 2:
out_record->year.has_value = true;
result = bebop_reader_read_uint16(reader, &out_record->year.value);
if (result != BEBOP_OK) return result;
break;
case 3:
out_record->performers.has_value = true;
uint32_t array_length_2;
result = bebop_reader_read_uint32(reader, &array_length_2);
if (result != BEBOP_OK) return result;
out_record->performers.value.length = array_length_2;
if (array_length_2 > 0) {
out_record->performers.value.data = (musician_t*)bebop_context_alloc(
reader->context, array_length_2 * sizeof(musician_t));
if (!out_record->performers.value.data)
return BEBOP_ERROR_OUT_OF_MEMORY;
for (size_t i2 = 0; i2 < array_length_2; i2++) {
result = musician_decode_into(
reader, &out_record->performers.value.data[i2]);
if (result != BEBOP_OK) return result;
}
} else {
out_record->performers.value.data = NULL;
}
break;
default:
bebop_reader_seek(reader, end);
return BEBOP_OK;
}
}
return BEBOP_OK;
}
bebop_result_t song_decode(bebop_reader_t* reader, song_t* out_record) {
return song_decode_into(reader, out_record);
}
size_t song_encoded_size(const song_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += 5;
if (bebop_is_some(record->title)) {
byte_count += sizeof(uint8_t);
byte_count += sizeof(uint32_t) + bebop_unwrap(record->title).length;
}
if (bebop_is_some(record->year)) {
byte_count += sizeof(uint8_t);
byte_count += sizeof(uint16_t);
}
if (bebop_is_some(record->performers)) {
byte_count += sizeof(uint8_t);
{
byte_count += sizeof(uint32_t);
for (size_t i0 = 0; i0 < bebop_unwrap(record->performers).length; i0++) {
byte_count +=
musician_encoded_size(&bebop_unwrap(record->performers).data[i0]);
}
}
}
return byte_count;
}
size_t song_max_encoded_size(const song_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += 5;
if (bebop_is_some(record->title)) {
byte_count += sizeof(uint8_t);
byte_count += sizeof(uint32_t) + (bebop_unwrap(record->title).length *
4); /* Max UTF-8 bytes per char */
}
if (bebop_is_some(record->year)) {
byte_count += sizeof(uint8_t);
byte_count += sizeof(uint16_t);
}
if (bebop_is_some(record->performers)) {
byte_count += sizeof(uint8_t);
{
byte_count += sizeof(uint32_t);
for (size_t i0 = 0; i0 < bebop_unwrap(record->performers).length; i0++) {
byte_count += musician_max_encoded_size(
&bebop_unwrap(record->performers).data[i0]);
}
}
}
return byte_count;
}
bebop_result_t library_encode_into(const library_t* record,
bebop_writer_t* writer) {
if (!record || !writer) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
result = bebop_writer_write_uint32(writer, (uint32_t)record->songs.length);
if (result != BEBOP_OK) return result;
for (size_t i0 = 0; i0 < record->songs.length; i0++) {
result = bebop_writer_write_guid(writer, record->songs.entries[i0].key);
if (result != BEBOP_OK) return result;
result = song_encode_into(&record->songs.entries[i0].value, writer);
if (result != BEBOP_OK) return result;
}
return BEBOP_OK;
}
bebop_result_t library_encode(const library_t* record, bebop_writer_t* writer) {
return library_encode_into(record, writer);
}
bebop_result_t library_decode_into(bebop_reader_t* reader,
library_t* out_record) {
if (!reader || !out_record) return BEBOP_ERROR_NULL_POINTER;
bebop_result_t result;
uint32_t map_length_0;
result = bebop_reader_read_uint32(reader, &map_length_0);
if (result != BEBOP_OK) return result;
out_record->songs.length = map_length_0;
if (map_length_0 > 0) {
out_record->songs.entries =
(bebop_guid_song_map_entry_t*)bebop_context_alloc(
reader->context,
map_length_0 * sizeof(bebop_guid_song_map_entry_t));
if (!out_record->songs.entries) return BEBOP_ERROR_OUT_OF_MEMORY;
for (size_t i0 = 0; i0 < map_length_0; i0++) {
result =
bebop_reader_read_guid(reader, &out_record->songs.entries[i0].key);
if (result != BEBOP_OK) return result;
result = song_decode_into(reader, &out_record->songs.entries[i0].value);
if (result != BEBOP_OK) return result;
}
} else {
out_record->songs.entries = NULL;
}
return BEBOP_OK;
}
bebop_result_t library_decode(bebop_reader_t* reader, library_t* out_record) {
return library_decode_into(reader, out_record);
}
size_t library_encoded_size(const library_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t);
for (size_t i0 = 0; i0 < record->songs.length; i0++) {
byte_count += 16;
byte_count += song_encoded_size(&record->songs.entries[i0].value);
}
return byte_count;
}
size_t library_max_encoded_size(const library_t* record) {
if (!record) return 0;
size_t byte_count = 0;
byte_count += sizeof(uint32_t);
for (size_t i0 = 0; i0 < record->songs.length; i0++) {
byte_count += 16;
byte_count += song_max_encoded_size(&record->songs.entries[i0].value);
}
return byte_count;
}
// #endregion
/* Auto-generated by bebop compiler */
#ifndef JAZZ_H
#define JAZZ_H
#include "bebop.h"
#ifdef __cplusplus
extern "C" {
#endif
// #region Forward declarations
/**
* @typedef audio_data_t
* @brief Opaque handle to a audio_data object.
*/
typedef struct audio_data_t audio_data_t;
/**
* @typedef musician_t
* @brief Opaque handle to a musician object.
*
* test
*/
typedef struct musician_t musician_t;
/**
* @typedef song_t
* @brief Opaque handle to a song object.
*/
typedef struct song_t song_t;
/**
* @typedef library_t
* @brief Opaque handle to a library object.
*/
typedef struct library_t library_t;
// #endregion
// #region Enums and Constants
typedef enum {
INSTRUMENT_SAX = 0,
INSTRUMENT_TRUMPET = 1,
INSTRUMENT_CLARINET = 2,
} instrument_t;
// #endregion
// #region Record Definitions
struct audio_data_t {
const bebop_float32_array_view_t samples;
};
BEBOP_DECLARE_ARRAY_ALLOC(audio_data, audio_data_t);
bebop_result_t audio_data_encode(const audio_data_t* record,
bebop_writer_t* writer);
bebop_result_t audio_data_decode(bebop_reader_t* reader,
audio_data_t* out_record);
bebop_result_t audio_data_encode_into(const audio_data_t* record,
bebop_writer_t* writer);
bebop_result_t audio_data_decode_into(bebop_reader_t* reader,
audio_data_t* out_record);
size_t audio_data_encoded_size(const audio_data_t* record);
size_t audio_data_max_encoded_size(const audio_data_t* record);
struct musician_t {
/** @brief a name */
const bebop_string_view_t name;
/** @brief an instrument */
const instrument_t plays;
};
BEBOP_DECLARE_ARRAY_ALLOC(musician, musician_t);
bebop_result_t musician_encode(const musician_t* record,
bebop_writer_t* writer);
bebop_result_t musician_decode(bebop_reader_t* reader, musician_t* out_record);
bebop_result_t musician_encode_into(const musician_t* record,
bebop_writer_t* writer);
bebop_result_t musician_decode_into(bebop_reader_t* reader,
musician_t* out_record);
size_t musician_encoded_size(const musician_t* record);
size_t musician_max_encoded_size(const musician_t* record);
struct song_t {
bebop_optional(bebop_string_view_t) title;
bebop_optional(uint16_t) year;
bebop_optional(bebop_musician_array_t) performers;
};
BEBOP_DECLARE_ARRAY_ALLOC(song, song_t);
BEBOP_DECLARE_MAP_ALLOC(guid, bebop_guid_t, song, song_t);
bebop_result_t song_encode(const song_t* record, bebop_writer_t* writer);
bebop_result_t song_decode(bebop_reader_t* reader, song_t* out_record);
bebop_result_t song_encode_into(const song_t* record, bebop_writer_t* writer);
bebop_result_t song_decode_into(bebop_reader_t* reader, song_t* out_record);
size_t song_encoded_size(const song_t* record);
size_t song_max_encoded_size(const song_t* record);
struct library_t {
bebop_guid_song_map_t songs;
};
BEBOP_DECLARE_ARRAY_ALLOC(library, library_t);
bebop_result_t library_encode(const library_t* record, bebop_writer_t* writer);
bebop_result_t library_decode(bebop_reader_t* reader, library_t* out_record);
bebop_result_t library_encode_into(const library_t* record,
bebop_writer_t* writer);
bebop_result_t library_decode_into(bebop_reader_t* reader,
library_t* out_record);
size_t library_encoded_size(const library_t* record);
size_t library_max_encoded_size(const library_t* record);
// #endregion
#ifdef __cplusplus
}
#endif
#endif /* JAZZ_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment