Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

[[ Perf ]] General features and improvements aimed at optimization #6671

Open
wants to merge 19 commits into
base: develop
Choose a base branch
Loading
from

Conversation

runrevmark
Copy link
Contributor

@runrevmark runrevmark commented Aug 31, 2018

This patch contains a number of relatively small, localized changes both improving performance adding features which help improve performance.

Integer indicies in arrays are much more efficient.

Short array path stores and fetches (<= 6 elements at the moment) are much more efficient.

Switch statements which only have constant cases are as efficient as they can be (constant time, rather than linear in the number of cases).

The list of parameters passed to a handler can now be fetched as a sequence starting at any index.

Arrays and sequences can now be expressed as literals - when the literals are constant, they are unique values, and evaluate with no overhead.

This patch adds the MCStringIsInteger method which checks that
the given string is a strict integer - i.e. one matching the
regex -?(0|[1-9][0-9]*).
This patch ensures that MCNumberParseOffset respects the integer_only
flag when the string is unicode.
This patch adds various benchmarks both from user suggestions
and internal work.
This patch adds a 'MakeUnique' method to the value-ref auto
classes which attempts to uniquify the value held in the
auto instance.
This patch adds PE_OUT_OF_MEMORY which is used if parsing a
construct results in a memory error.
This patch adds tests which report information about the sizes
of each of the libfoundation core (internal) type structures and
also attempts to illustrate the actual overhead of small blocks
allocated with malloc.
This patch minimises the size of the libfoundatino core value
structures. Specifically it shifts the order of some fields in
__MCString and __MCData resulting in a reduction in size on
64-bit, and moves the __MCName hash field into the __MCValue
flags word (at the expense of losing 5 bits of hash).

The effect on this on memory utilization will vary depending
on platform and architecture - most critically, the effacy of
the implementatin of malloc for small object sizes.

However, on 64-bit Mac, it means that __MCName and __MCString
will both fit into a 32-byte (no overhead) malloc block, as
opposed to a 48-byte (no overhead) malloc block as occurred
previously.
This patch modifies MCContainer so that it can hold a short
array path as part of itself, rather than requiring a memory
allocation. Longer paths will fall back to using a dynamically
allocated array.
This patch introduces the concept of an 'index' MCNameRef, one which
is generated from an index_t value.

Index names have optimized code paths for conversion of the index to
a string, hashing and insertion into the name table - all taking
advantage of the unique properties integer strings have.
This patch implements 'tagged' numbers which allow 'small'
integers to be stored in the value-ref pointer itself, rather
than require a full __MCNumber struct to be allocated.

Currently, the bottom-most bit of the pointer field is used to
determine whether the number has its value stored in the pointer
field or not.

The CreateWithInteger number constructor will always create a
tagged number if the provided integer will fit in the remaining
bits of the pointer.

A CreateWithAlignedPointer constructor and associated
FetchAsAlignedPointer method has been added. These allow an
(unmanaged) pointer which is aligned with default pointer
alignment (e.g. typically 8 byte aligned on 32-bit and 16
byte aligned on 64-bit) to be represented as a MCNumberRef with
no overhead. Critically this allows the MCValueRef containers
to hold non-valueref pointers - allowing them to be used to
store pointer-based values which aren't valuerefs (as long as
the lifetime of such things are managed externally).
This patch implements the notion of expression attributes on
MCExpression AST nodes.

The MCExpression base-class has been augmented with a new
virtual method 'getattrs()', which returns an MCExpressionAttrs
struct.

The MCExpressionAttrs currently only has an 'IsConstant' member,
but could be expanded in the future to add more information about
the AST node.

The MCConstant and MCLiteral expression nodes return attrs with
IsConstant true.
This patch changes the extensions handler map to use a (tagged)
aligned pointer rather than a foreign value for the target
value, improving memory footprint.
@runrevmark runrevmark changed the base branch from develop-9.0 to develop November 7, 2018 11:16
@runrevmark runrevmark changed the title [[ Perf ]] Improvements to array access [[ Perf ]] General features and improvements aimed at optimization Nov 7, 2018
MCAutoValueRef t_ptr;
MCForeignValueCreate(kMCPointerTypeInfo, &t_ext, (MCForeignValueRef&)t_ptr);
MCAutoNumberRef t_ptr;
MCNumberCreateWithAlignedPointer(&t_ext, &t_ptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be t_ext(no &)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed :)

This patch adds a variant of the params function.

The params function can now take 0, 1 or 2 parameters.

Calling it with zero parameters has the same behavior as before -
it returns a stringified version of the call that was made.

Calling it with two parameters returns a range of parameters
as a numerically sequenced array. The first parameter indicates the
starting index (from 1), and the second parameter indicates the
finishing index (from 1). Both parameters may be negative, in which
case they are interpreted as being relative to 'the paramCount' in
the same way negative chunk indicies work.

If only one parameter is specified, the second is taken to be -1.
This patch implements sequence and array literal values.

Sequence literals have syntax:
```
'[' { <expr> , ',' } ']'
```

Array literals have syntax:
```
'{' { <string>|<integer> ':' <expr> , ',' } '}'
```

In both cases as much evaluation is done at parse-time as possible.

A base value is created containing all constant values, and is uniqued
meaning that there is only ever one instance of the same set of base-values
for such a literal in memory at once.

At runtime, any dynamic values are evaluated and overlaid on the base value.
This patch changes the implementation of __MCArrayIsEqualTo so that
it recurses to MCValueIsEqualTo on values. This should improve the
veracity of interring an array, as it will mean that two arrays
only need to have the same values as contents, regardless of whether
those values have been interred to inter to the same value.
This patch implements a new function 'try'. The try function
takes one or two parameters. The first parameter is the
expression to try and evaluate, and the second (optional)
parameter is the failure expression.

The first expression is executed and if an error is thrown
during evaluation, the second expression (if specified) is
evaluated. If there is no second expression then empty is
returned, and no error propagates.

The second expression may contain the literal 'error',
which will evaluate to the error which was thrown during
evaluation of the first expression.

If evaluating the second expression throws an error, then
that error is propagated.
This patch changes the expression parser to allow engine
function keywords as variables, as long as they are not
followed by '('.
This patch implements three 'meta' indicies 'first', 'last'
and 'next'. These literals can appear in an array index
expression.

The first and last literals map to the first index (1)
and the last index (the number of elements) of a sequence
(array). If they are used on a non-sequence array value an
error is thrown.

The next literal maps to the element after the last of a
sequence (array) - equivalent to using the number of elements
+ 1.
livecode-vulcan added a commit that referenced this pull request Jan 14, 2019
[[ Perf ]] Array access optimizations

This patch contains a subset of the patches from #6671 - specifically those aimed at improving the performance of array access. Specifically using an optimized code-path when generating an index name (i.e. a strict integer value), and using on-heap storage for short array paths (those up to 6 elements deep).
livecode-vulcan added a commit that referenced this pull request Jan 14, 2019
[[ Perf ]] Array access optimizations

This patch contains a subset of the patches from #6671 - specifically those aimed at improving the performance of array access. Specifically using an optimized code-path when generating an index name (i.e. a strict integer value), and using on-heap storage for short array paths (those up to 6 elements deep).
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.