Closed Bug 861974 Opened 11 years ago Closed 8 years ago

ArrayBuffer (typed array) dynamic property access is slower than regular JS array

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: pnkfelix, Unassigned)

References

Details

Attachments

(1 file)

Accessing a dynamic property that has been attached to an ArrayBuffer seems to slow down code.  At least, it is slowing down the inner loops of code that is also using a Uint8Array view on the array buffer.

I am going to attach a relevant benchmark to this ticket, but just to be clear, here is the relevant snippet of code:

    var data  = new Uint8Array(buf);
    var width = buf.width;
    var height = buf.height;
    var buf1  = new ArrayBuffer(data.length);
    var data1 = new Uint8Array(buf1);
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            var index = x + y * buf.width; // <-- buf.width makes all the difference
            data1[index] = 1+data[index];
        }
    }
    return buf1;

If one rewrites the code above to use `width` instead of `buf.width` in the inner loop, then things are much faster (e.g. 80x times faster in the benchmark here).

If one rewrites the code above to use regular JS arrays rather than typed arrays, but continues using `buf.width`, it is *also* much faster.  (That is, one loses more from the dynamic property access than one gains from the switch to typed arrays.)  That is the problem I am concerned about: Porting existing code on Array to use an ArrayBuffer instead (by attaching dynamic properties to the ArrayBuffer when necessary) will hit this road-block and prevent people from using typed arrays without more invasive code revisions.

The benchmark I am attaching has four functions, exploring the 2x2 dimensional space [Array, TypedArray] x [ReadVar, ReadProp].  Here's the executive summary comparing each way of fixing one axis of the space and varying the other:

ARRAY-VS-TYPED IMPROVEMENT                : 76%
ARRAY-VAR-VS-ARRAY-PROP IMPROVEMENT       : -8%
ARRAY-PROP-VS-TYPED-PROP IMPROVEMENT      : -961%
TYPED-VAR-VS-TYPED-PROP IMPROVEMENT       : -6991%

(the average runtimes, in milliseonds I think, are as follows, which should clarify the above ratios reported by the benchmark)
Array ReadVar:   ~36
Typed ReadVar:   ~10
Array ReadProp:  ~38
Typed ReadProp: ~415 -- ~798    // see below

The reason for that last range is because the reported value is consistently centered around 415 during one comparison, ARRAY-PROP-VS-TYPED-PROP, and is consistently centered around 798 during the TYPED-VAR-VS-TYPED-PROP comparison.
The problem is that ArrayBuffers are non-native, so our IC's etc don't work...
Bug 979480 will make them native objects, afaict.
Depends on: 979480
Bug 979480 helped some (I suppose, I didn't bisect or anything), but didn't fix everything: the third test is now better, the fourth worse:

ARRAY-VS-TYPED IMPROVEMENT                 : 81%
ARRAY-VAR-VS-ARRAY-PROP IMPROVEMENT        : -4%
ARRAY-PROP-VS-TYPED-PROP IMPROVEMENT       : 81%
TYPED-VAR-VS-TYPED-PROP IMPROVEMENT        : -11825%
Assignee: general → nobody
The performance issues seems to be fixed. New results with current SpiderMonkey: 

ARRAY-VS-TYPED ARRAY      AVERAGE: 59.8
ARRAY-VS-TYPED TYPEDARRAY AVERAGE  : 8
ARRAY-VS-TYPED ARR/TYP RATIO     : 7.475
ARRAY-VS-TYPED TYP/ARR RATIO     : 0.13377926421404682
ARRAY-VS-TYPED IMPROVEMENT       : 86%

ARRAY-VAR-VS-ARRAY-PROP ARRAY      AVERAGE: 61.6
ARRAY-VAR-VS-ARRAY-PROP DEREFARRAY AVERAGE  : 65.2
ARRAY-VAR-VS-ARRAY-PROP ARR/DER RATIO     : 0.9447852760736196
ARRAY-VAR-VS-ARRAY-PROP DER/ARR RATIO     : 1.0584415584415585
ARRAY-VAR-VS-ARRAY-PROP IMPROVEMENT       : -5%

ARRAY-PROP-VS-TYPED-PROP ARRAY      AVERAGE: 61.6
ARRAY-PROP-VS-TYPED-PROP DEREFTYPEDARRAY AVERAGE  : 8
ARRAY-PROP-VS-TYPED-PROP ARR/DER RATIO     : 7.7
ARRAY-PROP-VS-TYPED-PROP DER/ARR RATIO     : 0.12987012987012986
ARRAY-PROP-VS-TYPED-PROP IMPROVEMENT       : 87%

TYPED-VAR-VS-TYPED-PROP TYPEDARRAY      AVERAGE: 9.6
TYPED-VAR-VS-TYPED-PROP DEREFTYPEDARRAY AVERAGE  : 8.8
TYPED-VAR-VS-TYPED-PROP TYP/DER RATIO     : 1.0909090909090908
TYPED-VAR-VS-TYPED-PROP DER/TYP RATIO     : 0.9166666666666667
TYPED-VAR-VS-TYPED-PROP IMPROVEMENT       : 8%


There was a typo in the TYPED-VAR-VS-TYPED-PROP test: calcAR_DerefWidth was called instead of calcTA_DerefWidth for the typed array, but calcAR_DerefWidth was already primed for normal Arrays, so the JIT compiler generated non-optimal code for typed arrays. Without the typo fix, TYPED-VAR-VS-TYPED-PROP yields the following results:

TYPED-VAR-VS-TYPED-PROP TYPEDARRAY      AVERAGE: 10
TYPED-VAR-VS-TYPED-PROP DEREFTYPEDARRAY AVERAGE  : 864
TYPED-VAR-VS-TYPED-PROP TYP/DER RATIO     : 0.011574074074074073
TYPED-VAR-VS-TYPED-PROP DER/TYP RATIO     : 86.4
TYPED-VAR-VS-TYPED-PROP IMPROVEMENT       : -8540%
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: