Skip to content

adding the JsonShapeSerializer#3842

Open
pulimsr wants to merge 1 commit into
mainfrom
schema-serde
Open

adding the JsonShapeSerializer#3842
pulimsr wants to merge 1 commit into
mainfrom
schema-serde

Conversation

@pulimsr

@pulimsr pulimsr commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Adding the implementation for JsonShapeSerializer

Check all that applies:

  • Did a review by yourself.
  • Added proper tests to cover this PR. (If tests are not applicable, explain.)
  • Checked if this PR is a breaking (APIs have been changed) change.
  • Checked if this PR will not introduce cross-platform inconsistent behavior.
  • Checked if this PR would require a ReadMe/Wiki update.

Check which platforms you have built SDK on to verify the correctness of this PR.

  • Linux
  • Windows
  • Android
  • MacOS
  • IOS
  • Other Platforms

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@pulimsr pulimsr marked this pull request as ready for review June 9, 2026 18:45
return schema.GetMemberName();
}

void BeginStructure(const Schema&) {}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats goin on here, shouldnt we be adding something to the stack when we begin/end a structure?


void WriteBoolean(const Schema& schema, bool value) {
if (!m_stack.empty() && m_stack.back().isList) {
JsonValue v;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think we wanna declare a JsonValue value here because thats gunna make a heap allocation in cjson

Aws::Vector<JsonValue> listItems;
};

Aws::Vector<StackEntry> m_stack;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK i see the grand picture of this and this matches our performance profile issues. This is actually much more simple than you are making it, lets start with what we are trying to do:

  • we are prioritizing code gen to avoid a DOM/in memory tree representation of the object like cjson does
  • we are allocating all of the memory up front (or at least try to) so that that we're only allocating and deallocating memory once.

So to start JsonValue will NOT be used in this class. JsonValue calls cjson which will have a multiple heap allocations as it traverses the tree. so that is out the window.

We are going to make it simple we have a character buffer(your calling it a stack in this case), and we just write to it, nothing more.

The basic structure of this would look like

#include <vector>

class json_parser_no_dom {
public:
    json_parser_no_dom(size_t buffer_size) {
        buffer_.reserve(buffer_size);
    }
    json_parser_no_dom(const json_parser_no_dom &other) = delete;
    json_parser_no_dom(json_parser_no_dom &&other) noexcept = default;
    json_parser_no_dom & operator=(const json_parser_no_dom &other) = delete;
    json_parser_no_dom & operator=(json_parser_no_dom &&other) noexcept = default;

    //...
    std::string serialize() { return buffer_; }
private:
    std::string buffer_{};
};

where in this case the parser has a pre-allocated buffer to write stuff into. now we just put stuff into it.

class json_parser_no_dom {
public:
    void write_string(const std::string& str, const std::string& value) {
        buffer_.append("\"");
        buffer_.append(str);
        buffer_.append("\":");
        buffer_.append("\"");
        buffer_.append(value);
        buffer_.append("\"");
    }
};

where you could do something like

auto main() -> int {
    json_parser_no_dom json_parser{100};
    json_parser.begin_structure();
    json_parser.write_string("foo", "bar");
    json_parser.end_structure();
    std::cout << json_parser.serialize() << std::endl;
    return 0;
}

and see

{"foo":"bar"}

so at a very high level I think the problem here is that you are relying on JsonValue and cjson to do the hard parts, and that actually means you are performing heap allocations. what you want to do is rely on the schema for tree walking, and then you just dump the tree to a buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants