DRegexp creates too many transient objects #302

Closed
headius opened this Issue Sep 18, 2012 · 1 comment

Projects

None yet

1 participant

@headius
JRuby Team member

DRegexp, like DStr and DSymbol (see #301) is creating too many transient objects on the way to generating its regexp. This is due in part to the complexity of the logic for building regular expressions dynamically and negotiating encodings across all parts (RubyRegexp.preprocessDRegexp()).

For the following benchmark...

i = 1; 10000.times {/"foo#{i}bar/}

The interpreter creates 7 ByteList, 5 RubyString, 4 Encoding[], 1 RubyString[], 1 RegexpOptions, and 1 RubyRegexp, not counting byte[] used inside the ByteList instances. In the ideal case, I would expect this to create perhaps two ByteList, one RegexpOptions, and one RubyRegexp. There's an intermediate RubyString for the DNode portion that might be hard to eliminate as well.

We are many times faster than 1.9.3 here, but the excessive number of transient objects really needs to be fixed.

system ~/projects/jruby $ jruby -Xcompile.invokedynamic=true ../rubybench/bench/time/language/bench_dregexp.rb 3
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    2.330000   0.070000   2.400000 (  1.473000)
1m x10 /abcd#{foo}ijkl/u                   1.260000   0.000000   1.260000 (  1.127000)
1m x10 /abcd#{foo}ijkl/o                   0.330000   0.000000   0.330000 (  0.231000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    1.000000   0.010000   1.010000 (  0.985000)
1m x10 /abcd#{foo}ijkl/u                   1.050000   0.000000   1.050000 (  1.030000)
1m x10 /abcd#{foo}ijkl/o                   0.210000   0.000000   0.210000 (  0.178000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    1.020000   0.010000   1.030000 (  1.010000)
1m x10 /abcd#{foo}ijkl/u                   1.020000   0.010000   1.030000 (  1.008000)
1m x10 /abcd#{foo}ijkl/o                   0.180000   0.000000   0.180000 (  0.170000)

system ~/projects/jruby $ jruby -X-C ../rubybench/bench/time/language/bench_dregexp.rb 3
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    9.980000   0.100000  10.080000 (  9.007000)
1m x10 /abcd#{foo}ijkl/u                   9.890000   0.050000   9.940000 (  9.607000)
1m x10 /abcd#{foo}ijkl/o                   0.170000   0.000000   0.170000 (  0.165000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    9.690000   0.030000   9.720000 (  9.408000)
1m x10 /abcd#{foo}ijkl/u                   9.750000   0.040000   9.790000 (  9.599000)
1m x10 /abcd#{foo}ijkl/o                   0.160000   0.000000   0.160000 (  0.162000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    9.580000   0.030000   9.610000 (  9.353000)
1m x10 /abcd#{foo}ijkl/u                   9.690000   0.030000   9.720000 (  9.571000)
1m x10 /abcd#{foo}ijkl/o                   0.240000   0.000000   0.240000 (  0.182000)

system ~/projects/jruby $ ruby-1.9.3 ../rubybench/bench/time/language/bench_dregexp.rb 1
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                   40.740000   0.180000  40.920000 ( 40.914476)
1m x10 /abcd#{foo}ijkl/u                  43.190000   0.210000  43.400000 ( 43.410582)
1m x10 /abcd#{foo}ijkl/o                   0.160000   0.000000   0.160000 (  0.157724)
@headius headius added a commit that referenced this issue Jul 25, 2013
@headius headius Reduce object overhead for dregexp.
* Share a single Encoding[] for the fixedEnc out param
* Add a "light" path to element preprocessing, since the bytelist
  produced was not used.

See #302.

Performance improves as follows:

Before:

```
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    5.500000   0.150000   5.650000 (  2.164000)
1m x10 /abcd#{foo}ijkl/u                   1.850000   0.010000   1.860000 (  1.429000)
1m x10 /abcd#{foo}ijkl/o                   0.730000   0.010000   0.740000 (  0.402000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    1.180000   0.000000   1.180000 (  1.176000)
1m x10 /abcd#{foo}ijkl/u                   1.160000   0.010000   1.170000 (  1.092000)
1m x10 /abcd#{foo}ijkl/o                   0.100000   0.000000   0.100000 (  0.107000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    0.910000   0.000000   0.910000 (  0.902000)
1m x10 /abcd#{foo}ijkl/u                   0.930000   0.020000   0.950000 (  0.927000)
1m x10 /abcd#{foo}ijkl/o                   0.110000   0.000000   0.110000 (  0.108000)
```

After:

```
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    2.680000   0.090000   2.770000 (  1.431000)
1m x10 /abcd#{foo}ijkl/u                   1.360000   0.010000   1.370000 (  1.081000)
1m x10 /abcd#{foo}ijkl/o                   0.490000   0.000000   0.490000 (  0.275000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    0.830000   0.000000   0.830000 (  0.826000)
1m x10 /abcd#{foo}ijkl/u                   0.860000   0.010000   0.870000 (  0.850000)
1m x10 /abcd#{foo}ijkl/o                   0.120000   0.000000   0.120000 (  0.117000)
                                               user     system      total        real
1m x10 /abcd#{foo}ijkl/                    0.840000   0.000000   0.840000 (  0.824000)
1m x10 /abcd#{foo}ijkl/u                   0.860000   0.010000   0.870000 (  0.847000)
1m x10 /abcd#{foo}ijkl/o                   0.100000   0.000000   0.100000 (  0.107000)
```
862b067
@headius
JRuby Team member

There's more improvement possible, but my commit reduces the objects created in the following ways:

  • Share a single Encoding[] used for "out" param fixedEnc.
  • Do not copy all incoming string bytes to a new ByteList. This was done before, but the resulting ByteList was never used.

See the commit for perf improvement.

@headius headius closed this Jul 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment