Front page | perl.dbi.dev |
Postings from February 2012
Re: dPERINTERP/MY_CXT (was: speeding up XS_DBI_dispatch())
Thread Previous
|
Thread Next
From:
Dave Mitchell
Date:
February 10, 2012 07:27
Subject:
Re: dPERINTERP/MY_CXT (was: speeding up XS_DBI_dispatch())
Message ID:
20120210152724.GD3250@iabyn.com
On Thu, Jan 26, 2012 at 12:26:44PM +0000, Tim Bunce wrote:
> On Wed, Jan 25, 2012 at 05:37:13PM -0800, Jan Dubois wrote:
> > On Wed, 25 Jan 2012, Tim Bunce wrote:
> > > On Wed, Jan 25, 2012 at 04:14:07PM +0000, Dave Mitchell wrote:
> > >
> > > > PS - I'm specifically being paid only to fix a performance issue on
> > > > non-threaded builds, so I won't be looking at threaded issues. But
> > > > dPERINTERP looks like bad news on threaded builds.
> > >
> > > The dPERINTERP stuff was added by ActiveState years ago to support
> > > MULTIPLICITY. I don't remember the details now. I do recall that driver
> > > authors are encouraged to avoid using the DBIS macro due to the cost.
> > > There's rarely a need now as DBI handles carry a pointer to the
> > > dbi_state structure. The DBI::DBD docs say
> >
> > Sorry, only skimming the conversation, so maybe this is obvious to
> > you: PERINTERP was a prototype from the 5.005 days for the MY_CXT
> > stuff that is now in the code. If you look at 5.8.1, then you'll see
> > MY_CXT being almost identical to PERINTERP in DBI. But switching to
> > MY_CXT should give you performance benefits on later Perl versions,
> > which have an improved MY_CXT implementation.
>
> Great. Thanks Jan.
>
> Anyone want to take a shot at that?
I attach two patches; the first replaces dPERINTERP with dMY_THX,
while the second extends this to the DBIS stuff too.
The headline figure (YMMV etc) is that on a recent threaded perl, these
two patches collectively make my mysql empty test loop twice as fast!!! :
while ($sth->fetch) { $c++ }
On a perl < 5.10.0 (before dMY_THX was made much more efficient), the
speedup is less spectacular, but is still about 25%.
I'm assuming that these won't be applied until after the windows() fork
issue is fixed, so think of this email more as a preview.
The first fix is relatively straightforward, and is private to DBI.xs,
since the PERINTERP macros were kind of a prototype for MY_CXT anyway.
The second patch, which makes DBIS more efficient, is a lot more complex,
and more likely to break things (especially as it's changing a bunch of
macros that are directly #included by the DBD drivers. You may need to
bump API version numbers; I don't understand that bit.
It works by adding a C function, _dbi_state_lval(), to DBI.xs which
returns a pointer to the static(ish) dbistate struct that only DBI.xs
knows about. However, I couldn't find any way for DBD:: code to call
functions within DBI, so I did a little hack: I faked up an XS sub,
&DBI::_dbi_state_lval(), whose CvXSUB points to the _dbi_state_lval
function. Since _dbi_state_lval() isn't actually an XS function,
perl-level code that tries to call &DBI::_dbi_state_lval() will crash and
burn.
If anyone knows of a more elegant way to make a function from DBI.xs
available to DBD:: code, please let me know!
Anyway, at the DBD end of things, the code extracts the address of the
function from &DBI::_dbi_state_lval's CvXSUB slot, and caches it in
a static var. Then in threaded builds, DBIS expands to a call to a static
function that calls _dbi_state_lval() which returns &(MY_CXT.dbi_state).
In unthreaded builds, it just returns the value of a static var as normal.
Here are some timings; remember that MY_CXT was made a lot faster in
5.10.0, so I've included timings for 5.8.9 too. As you'd expect, only the
threaded build have a significant speed-up; I think the tiny speed-ups in
the non-threaded builds are just noise.
The three timings (in sec) for the basic while($sth->fetch){$c++} loop
are for:
(1) the baseline: r15128 plus my method cache code
(2) in addition, replace dPERINTERP with dMY_CXT
(3) in addition, fix DBIS
1 2 3
----- ------ ------
40.10 - 29.96 5.8.9 threaded, optimised
37.62 33.98 18.96 5.15.7 threaded, optimised
12.85 - 12.55 5.8.9 unthreaded, optimised
13.41 13.46 12.97 5.15.6 unthreaded, optimised
The big saving between (2) and (3) is due to DBD::mysql still using DBIS;
in particular, for every fetch call.
--
This email is confidential, and now that you have read it you are legally
obliged to shoot yourself. Or shoot a lawyer, if you prefer. If you have
received this email in error, place it in its original wrapping and return
for a full refund. By opening this email, you accept that Elvis lives.
Thread Previous
|
Thread Next