Project

Profile

Help

Bug #1974

closed

Performance regression with tail expressions

Added by Michael Kay over 10 years ago. Updated almost 10 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Byte code generation
Sprint/Milestone:
-
Start date:
2014-01-08
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

A "tail expression" here can be taken as a call on tail(), whether it is written as such, or in various other ways such as subsequence($x, 2), or remove($x,1), or $x[position() gt 1]. (This has nothing directly to do with tail call optimization, though the two things often appear in conjunction).

Tail expressions are handled specially in the interpreter to avoid repeated copying of the base sequence, to improve performance in the case where the code calls tail() as many times as there are items in the original sequence (typically in head-tail recursion). The normal implementation would be to create a Closure.

This special handling of tail expressions is happening only in interpreted code and not in generated bytecode. This results in a substantial performance regression (from 0.2 seconds to 25 seconds in the case submitted).

A possibly contributory factor is that any variable reference V used as the first operand of a filter expression V[P] is being marked as potentially indexable, even if P is a simple numeric predicate such as [1]. This results in the variable being materialized as an IndexedValue rather than a MemoClosure (see EnterpriseConfiguration.makeClosure()).

There is in fact a "TODO" in the code at LetExpressionCompiler line 209 that indicates the absence of this optimization in compiled code.

Please register to edit this issue

Also available in: Atom PDF