Skip to content

Commit 3d81783

Browse files
committed
object_hash supported through greedy approach
1 parent 0a67aad commit 3d81783

File tree

12 files changed

+1322
-27
lines changed

12 files changed

+1322
-27
lines changed

benchmarks/generic_benchmark.exs

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
# Jsonpatch Diff Performance Benchmark
2+
# Run with: mix run test/benchmark.exs
3+
4+
defmodule JsonpatchBenchmark do
5+
@doc """
6+
Prepare complex test cases for benchmarking
7+
"""
8+
def prepare_test_cases() do
9+
%{
10+
"Complex Maps - E-commerce Order" => %{
11+
doc: %{
12+
"order_id" => "12345",
13+
"customer" => %{
14+
"name" => "John Doe",
15+
"email" => "[email protected]",
16+
"address" => %{
17+
"street" => "123 Main St",
18+
"city" => "Springfield",
19+
"country" => "USA"
20+
}
21+
},
22+
"items" => %{
23+
"item1" => %{"name" => "Laptop", "price" => 999.99, "quantity" => 1},
24+
"item2" => %{"name" => "Mouse", "price" => 29.99, "quantity" => 2}
25+
},
26+
"status" => "pending",
27+
"total" => 1059.97
28+
},
29+
expected: %{
30+
"order_id" => "12345",
31+
"customer" => %{
32+
"name" => "John Doe",
33+
"email" => "[email protected]",
34+
"address" => %{
35+
"street" => "456 Oak Ave",
36+
"city" => "Springfield",
37+
"country" => "USA",
38+
"zipcode" => "12345"
39+
},
40+
"phone" => "+1-555-0123"
41+
},
42+
"items" => %{
43+
"item1" => %{"name" => "Gaming Laptop", "price" => 1299.99, "quantity" => 1},
44+
"item3" => %{"name" => "Keyboard", "price" => 79.99, "quantity" => 1}
45+
},
46+
"status" => "confirmed",
47+
"total" => 1379.98,
48+
"discount" => 50.00
49+
}
50+
},
51+
"Complex Lists - Task Management" => %{
52+
doc: [
53+
%{
54+
"id" => 1,
55+
"task" => "Write documentation",
56+
"priority" => "high",
57+
"completed" => false
58+
},
59+
%{"id" => 2, "task" => "Fix bug #123", "priority" => "medium", "completed" => true},
60+
%{"id" => 3, "task" => "Review PR", "priority" => "low", "completed" => false},
61+
%{"id" => 4, "task" => "Deploy to staging", "priority" => "high", "completed" => false},
62+
%{"id" => 5, "task" => "Update tests", "priority" => "medium", "completed" => true}
63+
],
64+
expected: [
65+
%{
66+
"id" => 1,
67+
"task" => "Write comprehensive documentation",
68+
"priority" => "high",
69+
"completed" => true
70+
},
71+
%{
72+
"id" => 6,
73+
"task" => "Optimize database queries",
74+
"priority" => "high",
75+
"completed" => false
76+
},
77+
%{"id" => 3, "task" => "Review PR", "priority" => "medium", "completed" => false},
78+
%{"id" => 7, "task" => "Setup monitoring", "priority" => "low", "completed" => false},
79+
%{
80+
"id" => 4,
81+
"task" => "Deploy to production",
82+
"priority" => "critical",
83+
"completed" => false
84+
}
85+
]
86+
},
87+
"Mixed Maps and Lists - Social Media Post" => %{
88+
doc: %{
89+
"post_id" => "abc123",
90+
"content" => "Just had an amazing day!",
91+
"author" => %{
92+
"username" => "johndoe",
93+
"followers" => 1250,
94+
"verified" => false
95+
},
96+
"comments" => [
97+
%{"user" => "alice", "text" => "Great to hear!", "likes" => 5},
98+
%{"user" => "bob", "text" => "Awesome!", "likes" => 3}
99+
],
100+
"tags" => ["happy", "life"],
101+
"metadata" => %{
102+
"created_at" => "2023-01-01T10:00:00Z",
103+
"location" => "New York",
104+
"device" => "mobile"
105+
}
106+
},
107+
expected: %{
108+
"post_id" => "abc123",
109+
"content" => "Just had an absolutely amazing day! #blessed",
110+
"author" => %{
111+
"username" => "johndoe",
112+
"followers" => 1275,
113+
"verified" => true,
114+
"display_name" => "John Doe"
115+
},
116+
"comments" => [
117+
%{"user" => "alice", "text" => "Great to hear! So happy for you!", "likes" => 8},
118+
%{"user" => "charlie", "text" => "Inspiring!", "likes" => 2},
119+
%{"user" => "bob", "text" => "Awesome!", "likes" => 3, "reply_to" => "alice"}
120+
],
121+
"tags" => ["happy", "life", "blessed", "inspiration"],
122+
"metadata" => %{
123+
"created_at" => "2023-01-01T10:00:00Z",
124+
"updated_at" => "2023-01-01T10:15:00Z",
125+
"location" => "New York",
126+
"device" => "mobile",
127+
"engagement_score" => 8.5
128+
},
129+
"reactions" => %{
130+
"likes" => 45,
131+
"shares" => 12,
132+
"hearts" => 23
133+
}
134+
}
135+
},
136+
"Deep Nesting - Configuration Tree" => %{
137+
doc: %{
138+
"application" => %{
139+
"name" => "MyApp",
140+
"version" => "1.0.0",
141+
"modules" => %{
142+
"authentication" => %{
143+
"enabled" => true,
144+
"providers" => %{
145+
"oauth" => %{
146+
"google" => %{"client_id" => "123", "scopes" => ["email", "profile"]},
147+
"github" => %{"client_id" => "456", "scopes" => ["user:email"]}
148+
},
149+
"local" => %{"enabled" => true, "password_policy" => %{"min_length" => 8}}
150+
}
151+
},
152+
"database" => %{
153+
"primary" => %{
154+
"host" => "localhost",
155+
"port" => 5432,
156+
"name" => "myapp_db",
157+
"pool" => %{"size" => 10, "timeout" => 5000}
158+
},
159+
"replica" => %{
160+
"host" => "replica.example.com",
161+
"port" => 5432,
162+
"name" => "myapp_db"
163+
}
164+
}
165+
}
166+
}
167+
},
168+
expected: %{
169+
"application" => %{
170+
"name" => "MyApp",
171+
"version" => "1.1.0",
172+
"modules" => %{
173+
"authentication" => %{
174+
"enabled" => true,
175+
"providers" => %{
176+
"oauth" => %{
177+
"google" => %{
178+
"client_id" => "123",
179+
"scopes" => ["email", "profile", "calendar"]
180+
},
181+
"github" => %{"client_id" => "789", "scopes" => ["user:email", "read:user"]},
182+
"microsoft" => %{"client_id" => "999", "scopes" => ["User.Read"]}
183+
},
184+
"local" => %{
185+
"enabled" => true,
186+
"password_policy" => %{"min_length" => 12, "require_symbols" => true}
187+
},
188+
"saml" => %{
189+
"enabled" => false,
190+
"metadata_url" => "https://sso.example.com/metadata"
191+
}
192+
}
193+
},
194+
"database" => %{
195+
"primary" => %{
196+
"host" => "db.example.com",
197+
"port" => 5432,
198+
"name" => "myapp_production",
199+
"pool" => %{"size" => 20, "timeout" => 10_000, "idle_timeout" => 30_000}
200+
},
201+
"cache" => %{
202+
"host" => "redis.example.com",
203+
"port" => 6379,
204+
"ttl" => 3600
205+
}
206+
},
207+
"monitoring" => %{
208+
"metrics" => %{"enabled" => true, "interval" => 60},
209+
"logging" => %{"level" => "info", "format" => "json"}
210+
}
211+
},
212+
"features" => %{
213+
"feature_flags" => %{"new_ui" => true, "beta_features" => false}
214+
}
215+
}
216+
}
217+
}
218+
}
219+
end
220+
221+
@doc """
222+
Run the benchmark
223+
"""
224+
def run_benchmark() do
225+
Benchee.run(
226+
%{
227+
# I was using it for performance comparision, now faster version is the default one
228+
# "Faster JsonPatch" => fn %{doc: doc, expected: expected} ->
229+
# Jsonpatch.Faster.diff(doc, expected)
230+
# end,
231+
"JsonPatch" => fn %{doc: doc, expected: expected} ->
232+
Jsonpatch.diff(doc, expected)
233+
end
234+
},
235+
inputs: prepare_test_cases(),
236+
warmup: 0.1,
237+
time: 0.5,
238+
memory_time: 0.2,
239+
reduction_time: 0.2,
240+
parallel: 2,
241+
formatters: [
242+
Benchee.Formatters.Console
243+
],
244+
print: [
245+
benchmarking: true,
246+
configuration: false,
247+
fast_warning: false
248+
]
249+
)
250+
end
251+
end
252+
253+
# Run the benchmark
254+
JsonpatchBenchmark.run_benchmark()

0 commit comments

Comments
 (0)