@@ -55,11 +55,11 @@ than 3x) advantage, which we haven't figured out how to explain yet.
55
55
56
56
```
57
57
# json.cpp
58
- 88 ns 2000x object_test()
59
- 304 ns 2000x deep_test()
60
- 816 ns 2000x parse_test()
61
- 1588 ns 2000x round_trip_test()
62
- 5838 ns 2000x json_test_suite()
58
+ 71 ns 2000x object_test()
59
+ 226 ns 2000x deep_test()
60
+ 675 ns 2000x parse_test()
61
+ 1309 ns 2000x round_trip_test()
62
+ 10462 ns 2000x json_test_suite()
63
63
64
64
# nlohmann::ordered_json
65
65
202 ns 2000x object_test()
@@ -79,28 +79,28 @@ Here's the code where it parses the incoming HTTP body and validates it.
79
79
80
80
``` cpp
81
81
// object<model, messages, ...>
82
- std::pair<Json::Status, Json> json = Json::parse(payload_);
83
- if (json.first != Json::success)
84
- return send_error(400 , Json::StatusToString(json.first ));
85
- if (!json.second. isObject())
82
+ auto [status, json] = jt:: Json::parse(std::string( payload_) );
83
+ if (status != jt:: Json::success)
84
+ return send_error(400 , jt:: Json::StatusToString(status ));
85
+ if (!json.isObject())
86
86
return send_error(400 , " JSON body must be an object" );
87
87
88
88
// fields openai documents that we don't support yet
89
- if (! json.second[ " tools" ].isNull( ))
89
+ if (json.contains( " tools" ))
90
90
return send_error(400 , " OpenAI tools field not supported yet" );
91
- if (! json.second[ " audio" ].isNull( ))
91
+ if (json.contains( " audio" ))
92
92
return send_error(400 , " OpenAI audio field not supported yet" );
93
93
94
94
// model: string
95
- Json& model = json.second [" model" ];
95
+ jt:: Json& model = json[" model" ];
96
96
if (!model.isString())
97
97
return send_error(400 , " JSON missing model string" );
98
- params->model = std::move( model.getString() );
98
+ params->model = model.getString();
99
99
100
100
// messages: array<object<role:string, content:string>>
101
- if (!json.second [" messages" ].isArray())
101
+ if (!json[" messages" ].isArray())
102
102
return send_error(400 , " JSON missing messages array" );
103
- std::vector<Json>& messages = json.second [" messages" ].getArray();
103
+ std::vector<Json>& messages = json[" messages" ].getArray();
104
104
if (messages.empty())
105
105
return send_error(400 , " JSON messages array is empty" );
106
106
for (Json& message : messages) {
@@ -112,9 +112,8 @@ Here's the code where it parses the incoming HTTP body and validates it.
112
112
return send_error(400, "message role not system user assistant");
113
113
if (!message["content"].isString())
114
114
return send_error(400, "message must have string content");
115
- params->messages.emplace_back(
116
- std::move (message[ "role"] .getString()),
117
- std::move(message[ "content"] .getString()));
115
+ params->messages.emplace_back(message["role"].getString(),
116
+ message["content"].getString());
118
117
}
119
118
120
119
// ...
@@ -126,7 +125,7 @@ Here's the code where it sends a response.
126
125
struct V1ChatCompletionResponse
127
126
{
128
127
std::string content;
129
- Json json;
128
+ jt:: Json json;
130
129
};
131
130
132
131
bool
@@ -140,27 +139,24 @@ Client::v1_chat_completions()
140
139
// ...
141
140
142
141
// setup response json
143
- response->json["id"].setString(generate_id());
144
- response->json["object"].setString("chat.completion");
145
- response->json["model"].setString(params->model);
146
- response->json["system_fingerprint"].setString(slot_->system_fingerprint_);
147
- response->json["choices"].setArray();
142
+ response->json["id"] = generate_id();
143
+ response->json["object"] = "chat.completion";
144
+ response->json["model"] = params->model;
145
+ response->json["system_fingerprint"] = slot_->system_fingerprint_;
148
146
Json& choice = response->json["choices"][0];
149
- choice.setObject();
150
- choice["index"].setLong(0);
151
- choice["logprobs"].setNull();
152
- choice["finish_reason"].setNull();
147
+ choice["index"] = 0;
148
+ choice["logprobs"] = nullptr;
149
+ choice["finish_reason"] = nullptr;
153
150
154
151
// initialize response
155
152
if (params->stream) {
156
153
char* p = append_http_response_message(obuf_.p, 200);
157
154
p = stpcpy(p, "Content-Type: text/event-stream\r\n");
158
155
if (!send_response_start(obuf_.p, p))
159
156
return false;
160
- choice["delta"].setObject();
161
- choice["delta"]["role"].setString("assistant");
162
- choice["delta"]["content"].setString("");
163
- response->json["created"].setLong(timespec_real().tv_sec);
157
+ choice["delta"]["role"] = "assistant";
158
+ choice["delta"]["content"] = "";
159
+ response->json["created"] = timespec_real().tv_sec;
164
160
response->content = make_event(response->json);
165
161
choice.getObject().erase("delta");
166
162
if (!send_response_chunk(response->content))
@@ -173,29 +169,26 @@ Client::v1_chat_completions()
173
169
for (;;) {
174
170
// do token generation ...
175
171
}
176
- choice["finish_reason"].setString( finish_reason) ;
172
+ choice["finish_reason"] = finish_reason;
177
173
178
174
// finalize response
179
175
cleanup_slot(this);
180
176
if (params->stream) {
181
- choice["delta"].setObject();
182
- choice["delta"]["content"].setString("");
183
- response->json["created"].setLong(timespec_real().tv_sec);
177
+ choice["delta"]["content"] = "";
178
+ response->json["created"] = timespec_real().tv_sec;
184
179
response->content = make_event(response->json);
185
180
choice.getObject().erase("delta");
186
181
if (!send_response_chunk(response->content))
187
182
return false;
188
183
return send_response_finish();
189
184
} else {
190
185
Json& usage = response->json["usage"];
191
- usage.setObject();
192
- usage["prompt_tokens"].setLong(prompt_tokens);
193
- usage["completion_tokens"].setLong(completion_tokens);
194
- usage["total_tokens"].setLong(completion_tokens + prompt_tokens);
195
- choice["message"].setObject();
196
- choice["message"]["role"].setString("assistant");
197
- choice["message"]["content"].setString(std::move(response->content));
198
- response->json["created"].setLong(timespec_real().tv_sec);
186
+ usage["prompt_tokens"] = prompt_tokens;
187
+ usage["completion_tokens"] = completion_tokens;
188
+ usage["total_tokens"] = completion_tokens + prompt_tokens;
189
+ choice["message"]["role"] = "assistant";
190
+ choice["message"]["content"] = std::move(response->content);
191
+ response->json["created"] = timespec_real().tv_sec;
199
192
char* p = append_http_response_message(obuf_.p, 200);
200
193
p = stpcpy(p, "Content-Type: application/json\r\n");
201
194
response->content = response->json.toStringPretty();
0 commit comments