cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Is there any performance impact of calling modelservice.save multiple times inside a loop

Former Member
1,364

Is there any performance impact of calling modelservice.save multiple times inside a loop

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Basically yes, that's not the more optimized way, so yes it has impact. Now this impact may be ignored depending on your needs in term of performance.

I would say, as any performance questions, that you have to try it to know if it's perfomant enough for you.

You shouldn't worry about that kind of optimization, as you can see with Andrew's tests we are speaking of micro-optimisation.

If you need really low response time, then using Transaction to limit the connections to DB will be the answer.

You can check the hybris ref : https://help.hybris.com/1808/hcd/8c7387f186691014922080f2e053216a.html

andyfletcher
Active Contributor
0 Kudos

My understanding is that each time you call save (and the model has been modified) there is a database update, unless you've got enableDelayedStore set to true for the transaction. So depending on how much you are updating you might want to save outside of the loop or set the transaction to not store in the database until the end. If your loop is very large then you're going to have other issues with memory so you'd want to consider batching your saves and commits.

Some really rudimentary Groovy to test this theory (bear in mind I've only averaged this over 5 runs)

Saving in the loop

 start = System.currentTimeMillis()
 (1..500).each {
     ex = modelService.create('Product')
     ex.code = "test${it}"
     ex.catalogVersion = catalogVersionService.getCatalogVersion('Default', 'Staged')
     try {
         p = flexibleSearchService.getModelByExample ex
     } catch (e) {
         p = ex
     }
     p.name += '!'
     modelService.save(p)
 }
 println "took ${System.currentTimeMillis() - start}ms"

times

 609
 619
 575
 650
 557
 ===
 avg = 602 ms

Saving outside the loop

 start = System.currentTimeMillis()
 items = []
 (1..500).each {
     ex = modelService.create('Product')
     ex.code = "test${it}"
     ex.catalogVersion = catalogVersionService.getCatalogVersion('Default', 'Staged')
     try {
         p = flexibleSearchService.getModelByExample ex
     } catch (de.hybris.platform.servicelayer.exceptions.ModelNotFoundException e) {
         p = ex
     }
     p.name += '!'
     items << p
 }
 modelService.saveAll(items)
 println "took ${System.currentTimeMillis() - start}ms"

times

 480
 502
 482
 465
 464
 ===
 avg = 479 ms

Delaying store

 start = System.currentTimeMillis()
 de.hybris.platform.tx.Transaction.current().enableDelayedStore(true)
 (1..500).each {
     ex = modelService.create('Product')
     ex.code = "test${it}"
     ex.catalogVersion = catalogVersionService.getCatalogVersion('Default', 'Staged')
     try {
         p = flexibleSearchService.getModelByExample ex
     } catch (e) {
         p = ex
     }
     p.name += '!'
     modelService.save(p)
 }
 println "took ${System.currentTimeMillis() - start}ms"

times

 519
 530
 531
 522
 494
 ===
 avg = 519 ms
Former Member
0 Kudos

Interesting, I wonder how many transactions are created when using "enableDelayedStore", is there less transactions than regular case? It seems slower than saveAll, saveAll only do one transaction right?

andyfletcher
Active Contributor
0 Kudos

Yeah, I was a bit surprised that there was a difference. The next step would be to enable the jdbc log whilst this was running and see what queries are being issued. I'm also not totally sure about the validity of this test when run from the hac because presumably it is only committing the transaction after the script has finished, which is actually after our timing finishes.