Skip to content

Commit 4da8c74

Browse files
committed
round0
1 parent 566ec6f commit 4da8c74

146 files changed

Lines changed: 63971 additions & 63245 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

frameworks/actix/src/main.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ struct StaticFile {
5858

5959
struct AppState {
6060
dataset: Vec<DatasetItem>,
61-
json_cache: Vec<u8>,
6261
json_large_cache: Vec<u8>,
6362
static_files: HashMap<String, StaticFile>,
6463
}
@@ -225,10 +224,26 @@ async fn baseline2(req: HttpRequest) -> HttpResponse {
225224
}
226225

227226
async fn json_endpoint(state: web::Data<Arc<AppState>>) -> HttpResponse {
227+
if state.dataset.is_empty() {
228+
return HttpResponse::InternalServerError().body("No dataset");
229+
}
230+
let items: Vec<ProcessedItem> = state.dataset.iter().map(|d| ProcessedItem {
231+
id: d.id,
232+
name: d.name.clone(),
233+
category: d.category.clone(),
234+
price: d.price,
235+
quantity: d.quantity,
236+
active: d.active,
237+
tags: d.tags.clone(),
238+
rating: RatingOut { score: d.rating.score, count: d.rating.count },
239+
total: (d.price * d.quantity as f64 * 100.0).round() / 100.0,
240+
}).collect();
241+
let resp = JsonResponse { count: items.len(), items };
242+
let body = serde_json::to_vec(&resp).unwrap_or_default();
228243
HttpResponse::Ok()
229244
.insert_header((SERVER, SERVER_HDR.clone()))
230245
.content_type(ContentType::json())
231-
.body(state.json_cache.clone())
246+
.body(body)
232247
}
233248

234249
async fn compression(state: web::Data<Arc<AppState>>) -> HttpResponse {
@@ -273,7 +288,6 @@ fn load_tls_config() -> Option<ServerConfig> {
273288
#[actix_web::main]
274289
async fn main() -> io::Result<()> {
275290
let dataset = load_dataset();
276-
let json_cache = build_json_cache(&dataset);
277291

278292
let large_dataset: Vec<DatasetItem> = match std::fs::read_to_string("/data/dataset-large.json") {
279293
Ok(data) => serde_json::from_str(&data).unwrap_or_default(),
@@ -283,7 +297,6 @@ async fn main() -> io::Result<()> {
283297

284298
let state = Arc::new(AppState {
285299
dataset,
286-
json_cache,
287300
json_large_cache,
288301
static_files: load_static_files(),
289302
});

frameworks/bun/server.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,8 @@ const MIME_TYPES: Record<string, string> = {
77
".woff2": "font/woff2", ".svg": "image/svg+xml", ".webp": "image/webp", ".json": "application/json",
88
};
99

10-
// Pre-load dataset
11-
const data = JSON.parse(fs.readFileSync("/data/dataset.json", "utf8"));
12-
const items = data.map((d: any) => ({
13-
id: d.id, name: d.name, category: d.category,
14-
price: d.price, quantity: d.quantity, active: d.active,
15-
tags: d.tags, rating: d.rating,
16-
total: Math.round(d.price * d.quantity * 100) / 100,
17-
}));
18-
const jsonResponseBuf = Buffer.from(JSON.stringify({ items, count: items.length }));
10+
// Load raw dataset for per-request JSON processing
11+
const datasetItems: any[] = JSON.parse(fs.readFileSync("/data/dataset.json", "utf8"));
1912

2013
// Pre-load large dataset for /compression endpoint (compressed per-request)
2114
const largeData = JSON.parse(fs.readFileSync("/data/dataset-large.json", "utf8"));
@@ -110,8 +103,15 @@ function handleRequest(req: Request): Response | Promise<Response> {
110103
}
111104

112105
if (path === "/json") {
113-
return new Response(jsonResponseBuf, {
114-
headers: { "content-type": "application/json", "content-length": String(jsonResponseBuf.length) },
106+
const items = datasetItems.map((d: any) => ({
107+
id: d.id, name: d.name, category: d.category,
108+
price: d.price, quantity: d.quantity, active: d.active,
109+
tags: d.tags, rating: d.rating,
110+
total: Math.round(d.price * d.quantity * 100) / 100,
111+
}));
112+
const body = JSON.stringify({ items, count: items.length });
113+
return new Response(body, {
114+
headers: { "content-type": "application/json", "content-length": String(Buffer.byteLength(body)) },
115115
});
116116
}
117117

frameworks/caddy/handler.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,19 @@ type staticFile struct {
5353
contentType string
5454
}
5555

56+
type RawItem struct {
57+
ID int `json:"id"`
58+
Name string `json:"name"`
59+
Category string `json:"category"`
60+
Price float64 `json:"price"`
61+
Quantity int `json:"quantity"`
62+
Active bool `json:"active"`
63+
Tags []string `json:"tags"`
64+
Rating Rating `json:"rating"`
65+
}
66+
5667
type Handler struct {
57-
jsonResponse []byte
68+
dataset []RawItem
5869
jsonLargeResponse []byte
5970
staticFiles map[string]staticFile
6071
db *sql.DB
@@ -77,29 +88,9 @@ func (h *Handler) Provision(ctx caddy.Context) error {
7788
return nil // dataset not available, /json will 500
7889
}
7990

80-
var dataset []struct {
81-
ID int `json:"id"`
82-
Name string `json:"name"`
83-
Category string `json:"category"`
84-
Price float64 `json:"price"`
85-
Quantity int `json:"quantity"`
86-
Active bool `json:"active"`
87-
Tags []string `json:"tags"`
88-
Rating Rating `json:"rating"`
89-
}
90-
if err := json.Unmarshal(data, &dataset); err != nil {
91+
if err := json.Unmarshal(data, &h.dataset); err != nil {
9192
return nil
9293
}
93-
items := make([]ProcessedItem, len(dataset))
94-
for i, d := range dataset {
95-
items[i] = ProcessedItem{
96-
ID: d.ID, Name: d.Name, Category: d.Category,
97-
Price: d.Price, Quantity: d.Quantity, Active: d.Active,
98-
Tags: d.Tags, Rating: d.Rating,
99-
Total: math.Round(d.Price*float64(d.Quantity)*100) / 100,
100-
}
101-
}
102-
h.jsonResponse, _ = json.Marshal(ProcessResponse{Items: items, Count: len(items)})
10394

10495
// Load large dataset for /compression
10596
largeData, err := os.ReadFile("/data/dataset-large.json")
@@ -186,11 +177,21 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
186177
return nil
187178

188179
case "/json":
189-
if h.jsonResponse != nil {
180+
if h.dataset != nil {
181+
items := make([]ProcessedItem, len(h.dataset))
182+
for i, d := range h.dataset {
183+
items[i] = ProcessedItem{
184+
ID: d.ID, Name: d.Name, Category: d.Category,
185+
Price: d.Price, Quantity: d.Quantity, Active: d.Active,
186+
Tags: d.Tags, Rating: d.Rating,
187+
Total: math.Round(d.Price*float64(d.Quantity)*100) / 100,
188+
}
189+
}
190+
resp, _ := json.Marshal(ProcessResponse{Items: items, Count: len(items)})
190191
w.Header().Set("Content-Type", "application/json")
191192
w.Header().Set("Server", "caddy")
192-
w.Header().Set("Content-Length", strconv.Itoa(len(h.jsonResponse)))
193-
w.Write(h.jsonResponse)
193+
w.Header().Set("Content-Length", strconv.Itoa(len(resp)))
194+
w.Write(resp)
194195
} else {
195196
http.Error(w, "No dataset", 500)
196197
}

frameworks/deno/main.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
const datasetPath = Deno.env.get("DATASET_PATH") || "/data/dataset.json";
2-
let jsonResponseBytes: Uint8Array | undefined;
2+
let datasetItems: any[] | undefined;
33

44
try {
5-
const raw = JSON.parse(Deno.readTextFileSync(datasetPath));
6-
const items = raw.map((d: any) => ({
7-
id: d.id, name: d.name, category: d.category,
8-
price: d.price, quantity: d.quantity, active: d.active,
9-
tags: d.tags, rating: d.rating,
10-
total: Math.round(d.price * d.quantity * 100) / 100,
11-
}));
12-
jsonResponseBytes = new TextEncoder().encode(JSON.stringify({ items, count: items.length }));
5+
datasetItems = JSON.parse(Deno.readTextFileSync(datasetPath));
136
} catch { /* dataset not available */ }
147

158
const PLAIN = { "content-type": "text/plain", "server": "deno" };
@@ -44,8 +37,15 @@ export default {
4437
}
4538

4639
if (path === "/json") {
47-
if (jsonResponseBytes) {
48-
return new Response(jsonResponseBytes, {
40+
if (datasetItems) {
41+
const items = datasetItems.map((d: any) => ({
42+
id: d.id, name: d.name, category: d.category,
43+
price: d.price, quantity: d.quantity, active: d.active,
44+
tags: d.tags, rating: d.rating,
45+
total: Math.round(d.price * d.quantity * 100) / 100,
46+
}));
47+
const body = JSON.stringify({ items, count: items.length });
48+
return new Response(body, {
4949
headers: { "content-type": "application/json", "server": "deno" },
5050
});
5151
}

frameworks/drogon/main.cc

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static uint32_t crc32_compute(const void *data, size_t len) {
3434
return crc ^ 0xFFFFFFFF;
3535
}
3636

37-
static std::string json_response;
37+
static Json::Value dataset_root;
3838
static std::string json_large_response;
3939

4040
struct StaticFile {
@@ -55,34 +55,9 @@ static void loadDataset()
5555
f.close();
5656

5757
Json::CharReaderBuilder rb;
58-
Json::Value root;
5958
std::string errs;
6059
std::istringstream is(ss.str());
61-
if (!Json::parseFromStream(rb, is, &root, &errs) || !root.isArray()) return;
62-
63-
Json::Value resp;
64-
Json::Value items(Json::arrayValue);
65-
for (const auto &d : root) {
66-
Json::Value item;
67-
item["id"] = d["id"];
68-
item["name"] = d["name"];
69-
item["category"] = d["category"];
70-
item["price"] = d["price"];
71-
item["quantity"] = d["quantity"];
72-
item["active"] = d["active"];
73-
item["tags"] = d["tags"];
74-
item["rating"] = d["rating"];
75-
double price = d["price"].asDouble();
76-
int qty = d["quantity"].asInt();
77-
item["total"] = std::round(price * qty * 100.0) / 100.0;
78-
items.append(std::move(item));
79-
}
80-
resp["items"] = std::move(items);
81-
resp["count"] = static_cast<int>(root.size());
82-
83-
Json::StreamWriterBuilder wb;
84-
wb["indentation"] = "";
85-
json_response = Json::writeString(wb, resp);
60+
Json::parseFromStream(rb, is, &dataset_root, &errs);
8661
}
8762

8863
static void loadDatasetLarge()
@@ -185,12 +160,33 @@ int main()
185160
}
186161

187162
if (path == "/json") {
188-
if (!json_response.empty()) {
189-
auto resp = HttpResponse::newHttpResponse();
190-
resp->setBody(json_response);
191-
resp->setContentTypeCode(CT_APPLICATION_JSON);
192-
resp->addHeader("Server", "drogon");
193-
return resp;
163+
if (dataset_root.isArray() && dataset_root.size() > 0) {
164+
Json::Value resp;
165+
Json::Value items(Json::arrayValue);
166+
for (const auto &d : dataset_root) {
167+
Json::Value item;
168+
item["id"] = d["id"];
169+
item["name"] = d["name"];
170+
item["category"] = d["category"];
171+
item["price"] = d["price"];
172+
item["quantity"] = d["quantity"];
173+
item["active"] = d["active"];
174+
item["tags"] = d["tags"];
175+
item["rating"] = d["rating"];
176+
double price = d["price"].asDouble();
177+
int qty = d["quantity"].asInt();
178+
item["total"] = std::round(price * qty * 100.0) / 100.0;
179+
items.append(std::move(item));
180+
}
181+
resp["items"] = std::move(items);
182+
resp["count"] = static_cast<int>(dataset_root.size());
183+
Json::StreamWriterBuilder wb;
184+
wb["indentation"] = "";
185+
auto httpResp = HttpResponse::newHttpResponse();
186+
httpResp->setBody(Json::writeString(wb, resp));
187+
httpResp->setContentTypeCode(CT_APPLICATION_JSON);
188+
httpResp->addHeader("Server", "drogon");
189+
return httpResp;
194190
}
195191
auto resp = HttpResponse::newHttpResponse();
196192
resp->setStatusCode(k500InternalServerError);

frameworks/express/app.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,11 @@ if (cluster.isPrimary) {
1111
app.disable('x-powered-by');
1212
app.set('etag', false);
1313

14-
// Pre-serialized JSON response
15-
let jsonResponseBuf;
14+
// Raw dataset for per-request JSON processing
15+
let datasetItems;
1616
const datasetPath = process.env.DATASET_PATH || '/data/dataset.json';
1717
try {
18-
const data = JSON.parse(fs.readFileSync(datasetPath, 'utf8'));
19-
const items = data.map(d => ({
20-
id: d.id, name: d.name, category: d.category,
21-
price: d.price, quantity: d.quantity, active: d.active,
22-
tags: d.tags, rating: d.rating,
23-
total: Math.round(d.price * d.quantity * 100) / 100
24-
}));
25-
jsonResponseBuf = Buffer.from(JSON.stringify({ items, count: items.length }));
18+
datasetItems = JSON.parse(fs.readFileSync(datasetPath, 'utf8'));
2619
} catch (e) {}
2720

2821
function sumQuery(query) {
@@ -39,12 +32,19 @@ if (cluster.isPrimary) {
3932
});
4033

4134
app.get('/json', (req, res) => {
42-
if (jsonResponseBuf) {
35+
if (datasetItems) {
36+
const items = datasetItems.map(d => ({
37+
id: d.id, name: d.name, category: d.category,
38+
price: d.price, quantity: d.quantity, active: d.active,
39+
tags: d.tags, rating: d.rating,
40+
total: Math.round(d.price * d.quantity * 100) / 100
41+
}));
42+
const buf = Buffer.from(JSON.stringify({ items, count: items.length }));
4343
res.writeHead(200, {
4444
'content-type': 'application/json',
45-
'content-length': jsonResponseBuf.length,
45+
'content-length': buf.length,
4646
'server': 'express'
47-
}).end(jsonResponseBuf);
47+
}).end(buf);
4848
} else {
4949
res.writeHead(500).end('No dataset');
5050
}

frameworks/flask/app.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@
66
app = Flask(__name__)
77
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
88

9-
# Pre-serialize JSON response
10-
json_response = None
9+
# Load raw dataset for per-request processing
10+
dataset_items = None
1111
dataset_path = os.environ.get('DATASET_PATH', '/data/dataset.json')
1212
try:
1313
with open(dataset_path) as f:
14-
data = json.load(f)
15-
items = []
16-
for d in data:
17-
item = dict(d)
18-
item['total'] = round(d['price'] * d['quantity'] * 100) / 100
19-
items.append(item)
20-
json_response = json.dumps({'items': items, 'count': len(items)})
14+
dataset_items = json.load(f)
2115
except Exception:
2216
pass
2317

@@ -65,8 +59,13 @@ def baseline2():
6559

6660
@app.route('/json')
6761
def json_endpoint():
68-
if json_response:
69-
resp = make_response(json_response)
62+
if dataset_items:
63+
items = []
64+
for d in dataset_items:
65+
item = dict(d)
66+
item['total'] = round(d['price'] * d['quantity'] * 100) / 100
67+
items.append(item)
68+
resp = make_response(json.dumps({'items': items, 'count': len(items)}))
7069
resp.content_type = 'application/json'
7170
resp.headers['Server'] = 'flask'
7271
return resp

0 commit comments

Comments
 (0)