Issue Details (XML | Word | Printable)

Key: PYFB-70
Type: Task Task
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Pavel Cisar
Reporter: Dominik Psenner
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Firebird driver for Python

executemany(operation, seq_of_parameters) appears to run slower than it should

Created: 09/Jan/17 10:51 AM   Updated: 15/Feb/17 12:03 PM
Component/s: None
Affects Version/s: 1.5
Fix Version/s: 1.7


 Description  « Hide
We are facing performance issues with executemany, meaning that the .net implementation of the firebird driver runs way faster when running prepared statements against a set of parameters than the python implementation does. We are talking about a speedup factor beyond 10, i.e. on the .net driver the same statement runs within 100ms where the python implementation takes longer than a second. Therefore we investigated whether the implementation is correct. Unfortunately to us it looks like executemany still prepares statements on every second item in the seq of parameters. See comments below, prefixed with #. Please note that we have not stepped through this with a debugger. Further, this issue relates to PYFB-60.

    def executemany(self, operation, seq_of_parameters):
        # prepare once, which is correct and was added to fix PYFB-60
        if not isinstance(operation,PreparedStatement):
            operation = self.prep(operation)
        for parameters in seq_of_parameters:
            # invoked multiple times for each item in the seq of parameters
            self.execute(operation, parameters)

    def execute(self, operation, parameters=None):
        # on the first item in the seq of parameters, this if is skipped because self._ps is None
        # on the second item in the seq of parameters, this if is executed because self._ps is not None and thus the prepared statement resources are cleaned up
        if self._ps != None:
            self._ps.close()
        if not self._transaction.active:
            self._transaction.begin()
        if isinstance(operation, PreparedStatement):
            if operation.cursor is not self:
                raise ValueError("PreparedStatement was created by different Cursor.")
            self._ps = weakref.proxy(operation, _weakref_callback(self.__ps_deleted))
        else:
            self._ps = PreparedStatement(operation, self, True)
        # on the first item in the seq of parameters this invoke uses the prepared statement
        # on the second item in the seq of parameters this invoke will cause another prepare of the prepared statement because it was closed earlier
        self._ps._execute(parameters)

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Pavel Cisar made changes - 12/Jan/17 02:23 PM
Field Original Value New Value
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 1.7 [ 10803 ]
Resolution Fixed [ 1 ]
Repository Revision Date User Message
Firebird #63662 Thu Jan 12 14:23:57 UTC 2017 pcisar - Fix for PYFB-70
Files Changed
MODIFY /python/fdb/trunk/fdb/fbcore.py
MODIFY /python/fdb/trunk/test/testfdb.py

Pavel Cisar made changes - 15/Feb/17 12:03 PM
Status Resolved [ 5 ] Closed [ 6 ]