17.0
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ebf695ea09 |
[IMP] pos_self_order: Avoid extra _get_attributes_by_ptal_id calls
This commit is a performance fix to improve the speed of opening the pos kiosk or QR code. `_get_attributes` method of pos_self_order's product.product extension will call `self.env["pos.session"]._get_attributes_by_ptal_id()` every time it is called. For *N* products, `_get_attributes` is called *N* times. This can lead to slow performance for high enough *N*, because `_get_attributes_by_ptal_id` method is slow, because it makes many `read` calls to product.attribute.value This commit lifts the call to `_get_attributes_by_ptal_id` higher in the call stack, so that it is only called once as opposed to *N* times. It passes its result into `_get_attributes` via context, which will re-call `_get_attributes_by_ptal_id` if it wasn't in context for backwards compatibility reasons. attributes must be deep copied within `_get_attributes`, because `_add_price_info_to_attributes` mutates the values within, which would invalidate future calls. The deep copy gives a fresh instance for each call, and only copies the applicable attributes so it shouldn't be large. In this particular customer's DB they have 1376 product.product records and their pos config's pricelist (id 36) has 1572 rules in it. Overall, based on the benchmarks below, this commit makes loading the pos about 4-5 times faster. Benchmarks: __Before commit__ _Customer DB_ product.product count == 1376 SQL query count ~= 5034 Time to load pos ~= 44 sec _Customer DB with more products_ product.product count == 3792 SQL query count ~= 9359 Time to load pos ~= 96 sec __After commit__ _Customer DB_ product.product count == 1376 SQL query count ~= 2360 Time to load pos ~= 8 sec _Customer DB with more products_ product.product count == 3792 SQL query count ~= 3906 Time to load pos ~= 22 sec closes odoo/odoo#162962 X-original-commit: f09db068ff3c5a4e8444885c0cdd28e4221cf024 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com> Signed-off-by: Zachary Hanham (zaha) <zaha@odoo.com> |
||
|
|
fcd66ee332 |
[IMP] point_of_sale: improve OrderLine.findAttribute speed
This commit addresses slow performance of the JS `OrderLine.findAttribute` method when `attributes_by_ptal_id` is exceedingly large. Before this commit, `findAttribute` would loop over all the values of `this.pos.attributes_by_ptal_id`, and filter out only the attributes that have at least one of the passed in ptal IDs (from the `values` parameter) within the attribute's "values" list. It would also modify the attribute to include a `"valuesForOrderLine"` key mapping to a list of all of the found ptal IDs from that attribute's values. This method becomes slow when `this.pos.attributes_by_ptal_id` is very large. Since it needs to loop over every single attribute. This commit provides a workaround to this slowness, by caching the search for valid attributes that this method performs in a lookup table. First, we construct the lookup table in `_processData` method of the `PosStore` class. `_add_ptal_ids_by_ptav_id` does this, by looping over all the values of all the attributes, mapping the ptav ID of the attribute to all the ptal IDs we find. Now, inside `findAttribute`, we will instead loop over each of the passed in `values`. For each value, we will retrieve the all the cached ptal IDs from `this.pos.ptal_ids_by_ptav_id` for the given value. Now that we have the ptal IDs, we can get all the corresponding attributes from `this.pos.attributes_by_ptal_id`. For each of those attributes, we can do the same modification from the original method by adding the `"valuesForOrderLine"` key/value. Finally we return all the modified attributes. This new method has a nested for loop, which may seem like a problem. But I believe that both the things being looped over (`values` and `this.pos.ptal_ids_by_ptav_id[value]`) should be very small compared to the potential size of `this.pos.attributes_by_ptal_id`. (43,000 in this customer's DB) `findAttributes` is called many times whenever the POS's numpad buttons are pressed, so this commit has the overall effect of drastically reducing the input latency for a numpad press. However, I do believe that this is a workaround, and the real problem is that the entire `attributes_by_ptal_id` is always passed to the POS, regardless of what products are actually being ordered. `attributes_by_ptal_id` should instead be incrementally fetched as products are ordered (if this is possible). Benchmarks (in customer DB): Before commit, each keypad press took around 1-3 seconds per Order Line present in the POS. For 11 products this was ~15 second latency. After commit, each keypad press is almost instant. The `ptal_ids_by_ptav_id` lookup table will consume additional memory, in this customer's DB I've estimated it to be about 0.3MB more memory. Taking memory snapshots in profiler shows no significant different between versions, however this is inconsistent. Will attach profiler results to PR. opw-3788840 closes odoo/odoo#159402 Signed-off-by: David Monnom (moda) <moda@odoo.com> |
||
|
|
5db82daa8d |
[FIX] pos_self_order: use stored fields to check if product "has_image"
For method `_get_product_for_ui` in pos_self_order's product.product extension, check fields `product_tmpl_id.image_128` and/or `image_variant_128` for the existance of an image on the product (`has_image` key). Previously, the field `image_1920` was used which has two issues: 1.) The 128 sized image should be preferred because it is 15x smaller than 1920. The whole image is loaded at this point, so the smallest-sized one should be used. 2.) `image_1920` is a computed, non-stored, field. This has the implication that the image will be processed, thus consuming more memory (even leading to a MemoryError on the customer's DB). This happens like so: a.) `_compute_image_1920` is called, which sets a value into `record.image_1920`. https://github.com/odoo/odoo/blob/38f37edad3da4a4547b73d971e053b0634067fa1/addons/product/models/product_product.py#L157 b.) Eventually `_image_process` is called, which performs memory intensive computations on the image. https://github.com/odoo/odoo/blob/38f37edad3da4a4547b73d971e053b0634067fa1/odoo/fields.py#L2550 So this can be avoided by implementing this commit, which will check the stored, non-computed fields instead. Memory benchmarks for allocations by `_get_self_order_data`: Done on customer DB with 1340 product.products, with a total of 776 images between them. Before commit: 1638.4 MiB + server memory limit reached After commit: 29.7 MiB total Total improvement of 55x less memory usage closes odoo/odoo#157900 Signed-off-by: Vlad Stroia (vlst) <vlst@odoo.com> |