1
16
17 package issue_test
18
19 import (
20 `bytes`
21 `compress/gzip`
22 `encoding/json`
23 `io/ioutil`
24 `reflect`
25 `testing`
26 `time`
27
28 . `github.com/bytedance/sonic`
29 `github.com/bytedance/sonic/option`
30 `github.com/stretchr/testify/require`
31 )
32
33 var jsonData = func() string {
34
35 b, err := ioutil.ReadFile("../testdata/synthea_fhir.json.gz")
36 if err != nil {
37 panic(err)
38 }
39 zr, err := gzip.NewReader(bytes.NewReader(b))
40 if err != nil {
41 panic(err)
42 }
43 data, err := ioutil.ReadAll(zr)
44 if err != nil {
45 panic(err)
46 }
47 return string(data)
48 }()
49
50 type (
51 syntheaRoot struct {
52 Entry []struct {
53 FullURL string `json:"fullUrl"`
54 Request *struct {
55 Method string `json:"method"`
56 URL string `json:"url"`
57 } `json:"request"`
58 Resource *struct {
59 AbatementDateTime time.Time `json:"abatementDateTime"`
60 AchievementStatus syntheaCode `json:"achievementStatus"`
61 Active bool `json:"active"`
62 Activity []struct {
63 Detail *struct {
64 Code syntheaCode `json:"code"`
65 Location syntheaReference `json:"location"`
66 Status string `json:"status"`
67 } `json:"detail"`
68 } `json:"activity"`
69 Address []syntheaAddress `json:"address"`
70 Addresses []syntheaReference `json:"addresses"`
71 AuthoredOn time.Time `json:"authoredOn"`
72 BillablePeriod syntheaRange `json:"billablePeriod"`
73 BirthDate string `json:"birthDate"`
74 CareTeam []struct {
75 Provider syntheaReference `json:"provider"`
76 Reference string `json:"reference"`
77 Role syntheaCode `json:"role"`
78 Sequence int64 `json:"sequence"`
79 } `json:"careTeam"`
80 Category []syntheaCode `json:"category"`
81 Claim syntheaReference `json:"claim"`
82 Class syntheaCoding `json:"class"`
83 ClinicalStatus syntheaCode `json:"clinicalStatus"`
84 Code syntheaCode `json:"code"`
85 Communication []struct {
86 Language syntheaCode `json:"language"`
87 } `json:"communication"`
88 Component []struct {
89 Code syntheaCode `json:"code"`
90 ValueQuantity syntheaCoding `json:"valueQuantity"`
91 } `json:"component"`
92 Contained []struct {
93 Beneficiary syntheaReference `json:"beneficiary"`
94 ID string `json:"id"`
95 Intent string `json:"intent"`
96 Payor []syntheaReference `json:"payor"`
97 Performer []syntheaReference `json:"performer"`
98 Requester syntheaReference `json:"requester"`
99 ResourceType string `json:"resourceType"`
100 Status string `json:"status"`
101 Subject syntheaReference `json:"subject"`
102 Type syntheaCode `json:"type"`
103 } `json:"contained"`
104 Created time.Time `json:"created"`
105 DeceasedDateTime time.Time `json:"deceasedDateTime"`
106 Description syntheaCode `json:"description"`
107 Diagnosis []struct {
108 DiagnosisReference syntheaReference `json:"diagnosisReference"`
109 Sequence int64 `json:"sequence"`
110 Type []syntheaCode `json:"type"`
111 } `json:"diagnosis"`
112 DosageInstruction []struct {
113 AsNeededBoolean bool `json:"asNeededBoolean"`
114 DoseAndRate []struct {
115 DoseQuantity *struct {
116 Value float64 `json:"value"`
117 } `json:"doseQuantity"`
118 Type syntheaCode `json:"type"`
119 } `json:"doseAndRate"`
120 Sequence int64 `json:"sequence"`
121 Timing *struct {
122 Repeat *struct {
123 Frequency int64 `json:"frequency"`
124 Period float64 `json:"period"`
125 PeriodUnit string `json:"periodUnit"`
126 } `json:"repeat"`
127 } `json:"timing"`
128 } `json:"dosageInstruction"`
129 EffectiveDateTime time.Time `json:"effectiveDateTime"`
130 Encounter syntheaReference `json:"encounter"`
131 Extension []syntheaExtension `json:"extension"`
132 Gender string `json:"gender"`
133 Goal []syntheaReference `json:"goal"`
134 ID string `json:"id"`
135 Identifier []struct {
136 System string `json:"system"`
137 Type syntheaCode `json:"type"`
138 Use string `json:"use"`
139 Value string `json:"value"`
140 } `json:"identifier"`
141 Insurance []struct {
142 Coverage syntheaReference `json:"coverage"`
143 Focal bool `json:"focal"`
144 Sequence int64 `json:"sequence"`
145 } `json:"insurance"`
146 Insurer syntheaReference `json:"insurer"`
147 Intent string `json:"intent"`
148 Issued time.Time `json:"issued"`
149 Item []struct {
150 Adjudication []struct {
151 Amount syntheaCurrency `json:"amount"`
152 Category syntheaCode `json:"category"`
153 } `json:"adjudication"`
154 Category syntheaCode `json:"category"`
155 DiagnosisSequence []int64 `json:"diagnosisSequence"`
156 Encounter []syntheaReference `json:"encounter"`
157 InformationSequence []int64 `json:"informationSequence"`
158 LocationCodeableConcept syntheaCode `json:"locationCodeableConcept"`
159 Net syntheaCurrency `json:"net"`
160 ProcedureSequence []int64 `json:"procedureSequence"`
161 ProductOrService syntheaCode `json:"productOrService"`
162 Sequence int64 `json:"sequence"`
163 ServicedPeriod syntheaRange `json:"servicedPeriod"`
164 } `json:"item"`
165 LifecycleStatus string `json:"lifecycleStatus"`
166 ManagingOrganization []syntheaReference `json:"managingOrganization"`
167 MaritalStatus syntheaCode `json:"maritalStatus"`
168 MedicationCodeableConcept syntheaCode `json:"medicationCodeableConcept"`
169 MultipleBirthBoolean bool `json:"multipleBirthBoolean"`
170 Name json.RawMessage `json:"name"`
171 NumberOfInstances int64 `json:"numberOfInstances"`
172 NumberOfSeries int64 `json:"numberOfSeries"`
173 OccurrenceDateTime time.Time `json:"occurrenceDateTime"`
174 OnsetDateTime time.Time `json:"onsetDateTime"`
175 Outcome string `json:"outcome"`
176 Participant []struct {
177 Individual syntheaReference `json:"individual"`
178 Member syntheaReference `json:"member"`
179 Role []syntheaCode `json:"role"`
180 } `json:"participant"`
181 Patient syntheaReference `json:"patient"`
182 Payment *struct {
183 Amount syntheaCurrency `json:"amount"`
184 } `json:"payment"`
185 PerformedPeriod syntheaRange `json:"performedPeriod"`
186 Period syntheaRange `json:"period"`
187 Prescription syntheaReference `json:"prescription"`
188 PrimarySource bool `json:"primarySource"`
189 Priority syntheaCode `json:"priority"`
190 Procedure []struct {
191 ProcedureReference syntheaReference `json:"procedureReference"`
192 Sequence int64 `json:"sequence"`
193 } `json:"procedure"`
194 Provider syntheaReference `json:"provider"`
195 ReasonCode []syntheaCode `json:"reasonCode"`
196 ReasonReference []syntheaReference `json:"reasonReference"`
197 RecordedDate time.Time `json:"recordedDate"`
198 Referral syntheaReference `json:"referral"`
199 Requester syntheaReference `json:"requester"`
200 ResourceType string `json:"resourceType"`
201 Result []syntheaReference `json:"result"`
202 Series []struct {
203 BodySite syntheaCoding `json:"bodySite"`
204 Instance []struct {
205 Number int64 `json:"number"`
206 SopClass syntheaCoding `json:"sopClass"`
207 Title string `json:"title"`
208 UID string `json:"uid"`
209 } `json:"instance"`
210 Modality syntheaCoding `json:"modality"`
211 Number int64 `json:"number"`
212 NumberOfInstances int64 `json:"numberOfInstances"`
213 Started string `json:"started"`
214 UID string `json:"uid"`
215 } `json:"series"`
216 ServiceProvider syntheaReference `json:"serviceProvider"`
217 Started time.Time `json:"started"`
218 Status string `json:"status"`
219 Subject syntheaReference `json:"subject"`
220 SupportingInfo []struct {
221 Category syntheaCode `json:"category"`
222 Sequence int64 `json:"sequence"`
223 ValueReference syntheaReference `json:"valueReference"`
224 } `json:"supportingInfo"`
225 Telecom []map[string]string `json:"telecom"`
226 Text map[string]string `json:"text"`
227 Total json.RawMessage `json:"total"`
228 Type json.RawMessage `json:"type"`
229 Use string `json:"use"`
230 VaccineCode syntheaCode `json:"vaccineCode"`
231 ValueCodeableConcept syntheaCode `json:"valueCodeableConcept"`
232 ValueQuantity syntheaCoding `json:"valueQuantity"`
233 VerificationStatus syntheaCode `json:"verificationStatus"`
234 } `json:"resource"`
235 } `json:"entry"`
236 ResourceType string `json:"resourceType"`
237 Type string `json:"type"`
238 }
239 syntheaCode struct {
240 Coding []syntheaCoding `json:"coding"`
241 Text string `json:"text"`
242 }
243 syntheaCoding struct {
244 Code string `json:"code"`
245 Display string `json:"display"`
246 System string `json:"system"`
247 Unit string `json:"unit"`
248 Value float64 `json:"value"`
249 }
250 syntheaReference struct {
251 Display string `json:"display"`
252 Reference string `json:"reference"`
253 }
254 syntheaAddress struct {
255 City string `json:"city"`
256 Country string `json:"country"`
257 Extension []syntheaExtension `json:"extension"`
258 Line []string `json:"line"`
259 PostalCode string `json:"postalCode"`
260 State string `json:"state"`
261 }
262 syntheaExtension struct {
263 URL string `json:"url"`
264 ValueAddress syntheaAddress `json:"valueAddress"`
265 ValueCode string `json:"valueCode"`
266 ValueDecimal float64 `json:"valueDecimal"`
267 ValueString string `json:"valueString"`
268 Extension []syntheaExtension `json:"extension"`
269 }
270 syntheaRange struct {
271 End time.Time `json:"end"`
272 Start time.Time `json:"start"`
273 }
274 syntheaCurrency struct {
275 Currency string `json:"currency"`
276 Value float64 `json:"value"`
277 }
278 )
279
280
281 func TestPretouchSynteaRoot(t *testing.T) {
282 m := new(syntheaRoot)
283 s := time.Now()
284 println("start decoder pretouch:", s.UnixNano())
285 require.Nil(t, Pretouch(reflect.TypeOf(m), option.WithCompileMaxInlineDepth(2), option.WithCompileRecursiveDepth(20)))
286 e := time.Now()
287 println("end decoder pretouch:", e.UnixNano())
288 println("elapsed:", e.Sub(s).Milliseconds(), "ms")
289
290 s = time.Now()
291 println("start decode:", s.UnixNano())
292 require.Nil(t, UnmarshalString(jsonData, m))
293 e = time.Now()
294 println("end decode:", e.UnixNano())
295 d1 := e.Sub(s).Nanoseconds()
296 println("elapsed:", d1, "ns")
297
298 s = time.Now()
299 println("start decode:", s.UnixNano())
300 require.Nil(t, UnmarshalString(jsonData, m))
301 e = time.Now()
302 println("end decode:", e.UnixNano())
303 d2 := e.Sub(s).Nanoseconds()
304 println("elapsed:", d2, "ns")
305 if d1 > d2 * 20 {
306 t.Fatal("decoder pretouch not finish yet")
307 }
308
309 s = time.Now()
310 println("start decode:", s.UnixNano())
311 require.Nil(t, UnmarshalString(jsonData, m))
312 e = time.Now()
313 println("end decode:", e.UnixNano())
314 d5 := e.Sub(s).Nanoseconds()
315 println("elapsed:", d5, "ns")
316 if d2 > d5 * 10 {
317 t.Fatal("decoder pretouch not finish yet")
318 }
319
320 s = time.Now()
321 println("start encode 1:", s.UnixNano())
322 _, err := MarshalString(*m)
323 require.Nil(t, err)
324 e = time.Now()
325 println("end encode 1:", e.UnixNano())
326 d3 := e.Sub(s).Nanoseconds()
327 println("elapsed:", d3, "ns")
328
329 s = time.Now()
330 println("start encode 2:", s.UnixNano())
331 _, err = MarshalString(m)
332 require.Nil(t, err)
333 e = time.Now()
334 println("end encode 2:", e.UnixNano())
335 d4 := e.Sub(s).Nanoseconds()
336 println("elapsed:", d4, "ns")
337
338
339
340
341 s = time.Now()
342 println("start encode 3:", s.UnixNano())
343 _, err = MarshalString(m)
344 require.Nil(t, err)
345 e = time.Now()
346 println("end encode 3:", e.UnixNano())
347 d6 := e.Sub(s).Nanoseconds()
348 println("elapsed:", d6, "ns")
349 if d4 > d6 * 10 {
350 t.Fatal("encoder pretouch not finish yet")
351 }
352 }
353
354 func BenchmarkDecodeSynteaRoot(b *testing.B) {
355 m := new(syntheaRoot)
356 require.Nil(b, Pretouch(reflect.TypeOf(m), option.WithCompileRecursiveDepth(10)))
357
358 b.SetBytes(int64(len(jsonData)))
359 b.ResetTimer()
360 for i := 0; i < b.N; i++ {
361 _ = UnmarshalString(jsonData, m)
362 }
363 }
364
365 func BenchmarkEncodeSynteaRoot(b *testing.B) {
366 m := new(syntheaRoot)
367 require.Nil(b, Pretouch(reflect.TypeOf(m), option.WithCompileRecursiveDepth(10)))
368 require.Nil(b, UnmarshalString(jsonData, m))
369
370 b.SetBytes(int64(len(jsonData)))
371 b.ResetTimer()
372 for i := 0; i < b.N; i++ {
373 _, _ = MarshalString(m)
374 }
375 }
View as plain text