Hello everyone, 

why this line is inside the loop?

https://github.com/odoo/odoo/blob/132c7e75e57321c77aac9250a2587c74c5da7857/addons/account/models/account_move.py#L1364

We were removing 100k~ account.move.line records for testing purposes. It took ages. So we do some little investigation and saw this, we took out from the loop the process duration became minutes from hours.

Regards from Projet
""" Create analytic items upon validation of an account.move.line having an analytic account. This
            method first remove any existing analytic item related to the line before creating any new one.
        """
        self.mapped('analytic_line_ids').unlink()
        for obj_line in self:
            if obj_line.analytic_account_id:
                vals_line = obj_line._prepare_analytic_line()[0]
                self.env['account.analytic.line'].create(vals_line)
    @api.one
    def _prepare_analytic_line(self):
        """ Prepare the values used to create() an account.analytic.line upon validation of an account.move.line having
            an analytic account. This method is intended to be extended in other modules.
        """
        amount = (self.credit or 0.0) - (self.debit or 0.0)
        return {
            'name': self.name,
            'date': self.date,
            'account_id': self.analytic_account_id.id,
            'unit_amount': self.quantity,
            'product_id': self.product_id and self.product_id.id or False,
            'product_uom_id': self.product_uom_id and self.product_uom_id.id or False,
            'amount': self.company_currency_id.with_context(date=self.date or fields.Date.context_today(self)).compute(amount, self.analytic_account_id.currency_id) if self.analytic_account_id.currency_id else amount,
            'general_account_id': self.account_id.id,
            'ref': self.ref,
            'move_id': self.id,
            'user_id': self.invoice_id.user_id.id or self._uid,
        }
    @api.model
    def _query_get(self, domain=None):