github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/issue_test/pretouch_test.go (about) 1 /* 2 * Copyright 2021 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 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 // Read and decompress the test data. 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 // if d3 > d4 * 10 { 338 // t.Fatal("encoder pretouch not finish yet") 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 }