Last active
June 19, 2025 13:55
-
-
Save andrewmd5/aaac0436befdcd5b12c555a8382a3bf9 to your computer and use it in GitHub Desktop.
Bebop C examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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