This question has been flagged
2 Replies
4501 Views

We have noted that this method is extremely expensive in terms of performance:

https://github.com/odoo/odoo/blob/8.0/openerp/api.py#L890

Specifically during the re-computation of stored function fields:

models:5877

    @api.model
    def recompute(self):
        """ Recompute stored function fields. The fields and records to
            recompute have been determined by method :meth:`modified`.
        """
        while self.env.has_todo():
            field, recs = self.env.get_todo()
            # evaluate the fields to recompute, and save them to database
            names = [
                f.name
                for f in field.computed_fields
                if f.store and self.env.field_todo(f)
            ]
            for rec in recs:
                try:
                    values = rec._convert_to_write({
                        name: rec[name] for name in names
                    })
                    with rec.env.norecompute():
                        rec._write(values)
                except MissingError:
                    pass
            # mark the computed fields as done
            map(recs._recompute_done, field.computed_fields)


api:890

    def field_todo(self, field):
        """ Check whether ``field`` must be recomputed, and returns a recordset
            with all records to recompute for ``field``.
        """
        if field in self.all.todo:
            return reduce(operator.or_, self.all.todo[field])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Is that really the fastest way? 

Avatar
Discard
Best Answer

I can't comment, so I'll  have to answer the question that's written below here.

That error occurs, because they're iterating over `Environment.all`, which ultimately means iterating over a `WeakSet`, and there was some Python bug in `WeakSet`s that caused the error.

`Environment.all.todo`, however, is an ordinary dictionary with lists as values, so there shouldn't be a problem.

Avatar
Discard
Author

I see that you have proposed a fix: https://github.com/OCA/OCB/pull/460 Thank you.

Author Best Answer

Does the self.all.todo iteration need to be protected the same way that the iteration of self.all  ?  (http://bit.ly/1RfxsL1)

https://github.com/odoo/odoo/issues/966

RuntimeError: Set changed size during iteration
Avatar
Discard