luau/tests
Arseny Kapoulkine f5303b3dd7
Make table.concat faster (#1243)
table.concat is idiomatic and should be the fastest way to concatenate
all table array elements together, but apparently you can beat it by
using `string.format`, `string.rep` and `table.unpack`:

```lua
string.format(string.rep("%*", #t), table.unpack(t))
```

... this just won't do, so we should fix table.concat performance.

The deficit comes from two places:

- rawgeti overhead followed by other stack accesses, all to extract a
string from what is almost always an in-bounds array lookup
- addlstring overhead in case separator is empty (extra function calls)

This change fixes this by using a fast path for in-bounds array lookup
for a string. Note that `table.concat` also supports numbers (these need
to be converted to strings which is a little cumbersome and has innate
overhead), and out-of-bounds accesses*. In these cases we fall back to
the old implementation.

To trigger out-of-bounds accesses, you need to skip the past-array-end
element (which is nil per array invariant), but this is achievable
because table.concat supports offset+length arguments. This should
almost never come up in practice but the per-element branches et al are
fairly cheap compared to the eventual string copy/alloc anyway.

This change makes table.concat ~2x faster when the separator is empty;
the table.concat benchmark shows +40% gains but it uses a variety of
string separators of different lengths so it doesn't get the full
benefit from this change.

---------

Co-authored-by: vegorov-rbx <75688451+vegorov-rbx@users.noreply.github.com>
2024-04-29 05:19:01 -07:00
..
conformance Make table.concat faster (#1243) 2024-04-29 05:19:01 -07:00
require Sync to upstream/release/607 (#1131) 2023-12-15 13:29:06 -08:00
AssemblyBuilderA64.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
AssemblyBuilderX64.test.cpp Sync to upstream/release/615 (#1175) 2024-03-01 10:45:26 -08:00
AstJsonEncoder.test.cpp Sync to upstream/release/613 (#1167) 2024-02-15 18:04:39 -08:00
AstQuery.test.cpp Sync to upstream/release/607 (#1131) 2023-12-15 13:29:06 -08:00
AstQueryDsl.cpp Sync to upstream/release/549 (#707) 2022-10-14 12:48:41 -07:00
AstQueryDsl.h Sync to upstream/release/549 (#707) 2022-10-14 12:48:41 -07:00
AstVisitor.test.cpp Sync to upstream/release/501 (#20) 2021-11-01 14:52:34 -07:00
Autocomplete.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
BuiltinDefinitions.test.cpp Sync to upstream/release/567 (#860) 2023-03-10 12:21:07 -08:00
ClassFixture.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
ClassFixture.h Sync to upstream/release/600 (#1076) 2023-10-20 18:10:30 -07:00
CodeAllocator.test.cpp Sync to upstream/release/597 (#1054) 2023-09-29 18:13:05 -07:00
Compiler.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
Config.test.cpp Sync to upstream/release/501 (#20) 2021-11-01 14:52:34 -07:00
Conformance.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
ConstraintGeneratorFixture.cpp Sync to upstream/release/605 (#1118) 2023-12-01 23:46:57 -08:00
ConstraintGeneratorFixture.h Sync to upstream/release/602 (#1089) 2023-11-03 16:45:04 -07:00
ConstraintSolver.test.cpp Sync to upstream/release/614 (#1173) 2024-02-23 12:08:34 -08:00
CostModel.test.cpp Sync to upstream/release/591 (#1012) 2023-08-18 11:15:41 -07:00
DataFlowGraph.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
DenseHash.test.cpp Sync to upstream/release/561 (#820) 2023-01-27 14:28:31 -08:00
DiffAsserts.cpp Sync to upstream/release/600 (#1076) 2023-10-20 18:10:30 -07:00
DiffAsserts.h Sync to upstream/release/613 (#1167) 2024-02-15 18:04:39 -08:00
Differ.test.cpp Sync to upstream/release/614 (#1173) 2024-02-23 12:08:34 -08:00
Error.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
Fixture.cpp Sync to upstream/release/615 (#1175) 2024-03-01 10:45:26 -08:00
Fixture.h Sync to upstream/release/609 (#1150) 2024-01-19 10:04:46 -08:00
Frontend.test.cpp Sync to upstream/release/615 (#1175) 2024-03-01 10:45:26 -08:00
InsertionOrderedMap.test.cpp Sync to upstream/release/580 (#951) 2023-06-09 10:08:00 -07:00
Instantiation2.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
IostreamOptional.h Sync to upstream/release/603 (#1097) 2023-11-10 13:10:07 -08:00
IrBuilder.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
IrCallWrapperX64.test.cpp Sync to upstream/release/601 (#1084) 2023-10-27 14:18:41 -07:00
IrLowering.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
IrRegAllocX64.test.cpp Sync to upstream/release/595 (#1044) 2023-09-15 10:26:59 -07:00
JsonEmitter.test.cpp Sync to upstream/release/543 (#657) 2022-09-01 16:14:03 -07:00
Lexer.test.cpp Sync to upstream/release/570 (#885) 2023-03-31 11:42:49 -07:00
Linter.test.cpp Sync to upstream/release/614 (#1173) 2024-02-23 12:08:34 -08:00
LValue.test.cpp Sync to upstream/release/557 (#794) 2023-01-04 12:53:17 -08:00
main.cpp Sync to upstream/release/613 (#1167) 2024-02-15 18:04:39 -08:00
Module.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
NonstrictMode.test.cpp Sync to upstream/release/574 (#910) 2023-04-28 12:55:13 -07:00
NonStrictTypeChecker.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
Normalize.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
NotNull.test.cpp Sync to upstream/release/555 (#768) 2022-12-02 10:09:59 -08:00
Parser.test.cpp Sync to upstream/release/609 (#1150) 2024-01-19 10:04:46 -08:00
RegisterCallbacks.cpp Sync to upstream/release/594 (#1036) 2023-09-07 17:13:49 -07:00
RegisterCallbacks.h Sync to upstream/release/594 (#1036) 2023-09-07 17:13:49 -07:00
Repl.test.cpp Sync to upstream/release/553 (#742) 2022-11-10 14:53:13 -08:00
RequireByString.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
RequireTracer.test.cpp Sync to upstream/release/514 (#372) 2022-02-17 17:18:01 -08:00
RuntimeLimits.test.cpp Sync to upstream/release/605 (#1118) 2023-12-01 23:46:57 -08:00
ScopedFlags.h Sync to upstream/release/616 (#1184) 2024-03-08 16:47:53 -08:00
Set.test.cpp Sync to upstream/release/618 (#1205) 2024-03-22 10:47:10 -07:00
SharedCodeAllocator.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
Simplify.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
StringUtils.test.cpp Sync to upstream/release/588 (#992) 2023-07-28 08:13:53 -07:00
Subtyping.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
Symbol.test.cpp Sync to upstream/release/605 (#1118) 2023-12-01 23:46:57 -08:00
ToDot.test.cpp Sync to upstream/release/611 (#1160) 2024-02-02 13:32:42 -08:00
TopoSort.test.cpp Sync to upstream/release/523 (#459) 2022-04-14 16:57:43 -07:00
ToString.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
Transpiler.test.cpp Sync to upstream/release/608 (#1145) 2024-01-12 14:25:27 -08:00
TxnLog.test.cpp Sync to upstream/release/605 (#1118) 2023-12-01 23:46:57 -08:00
TypeFamily.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.aliases.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.annotations.test.cpp Sync to upstream/release/613 (#1167) 2024-02-15 18:04:39 -08:00
TypeInfer.anyerror.test.cpp Sync to upstream/release/615 (#1175) 2024-03-01 10:45:26 -08:00
TypeInfer.builtins.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.cfa.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.classes.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.definitions.test.cpp Sync to upstream/release/608 (#1145) 2024-01-12 14:25:27 -08:00
TypeInfer.functions.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
TypeInfer.generics.test.cpp Sync to upstream/release/620 (#1223) 2024-04-05 13:45:09 -07:00
TypeInfer.intersectionTypes.test.cpp Sync to upstream/release/613 (#1167) 2024-02-15 18:04:39 -08:00
TypeInfer.loops.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
TypeInfer.modules.test.cpp Sync to upstream/release/620 (#1223) 2024-04-05 13:45:09 -07:00
TypeInfer.negations.test.cpp Sync to upstream/release/574 (#910) 2023-04-28 12:55:13 -07:00
TypeInfer.oop.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.operators.test.cpp Sync to upstream/release/616 (#1184) 2024-03-08 16:47:53 -08:00
TypeInfer.primitives.test.cpp Sync to upstream/release/600 (#1076) 2023-10-20 18:10:30 -07:00
TypeInfer.provisional.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.refinements.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.singletons.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.tables.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
TypeInfer.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
TypeInfer.tryUnify.test.cpp Sync to upstream/release/621 (#1229) 2024-04-12 10:18:49 -07:00
TypeInfer.typePacks.test.cpp Sync to upstream/release/608 (#1145) 2024-01-12 14:25:27 -08:00
TypeInfer.typestates.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.unionTypes.test.cpp Sync to upstream/release/622 (#1232) 2024-04-19 14:48:02 -07:00
TypeInfer.unknownnever.test.cpp Sync to upstream/release/607 (#1131) 2023-12-15 13:29:06 -08:00
TypePack.test.cpp Sync to upstream/release/571 (#895) 2023-04-07 14:01:29 -07:00
TypePath.test.cpp Sync to upstream/release/614 (#1173) 2024-02-23 12:08:34 -08:00
TypeVar.test.cpp Sync to upstream/release/597 (#1054) 2023-09-29 18:13:05 -07:00
Unifier2.test.cpp Sync to upstream/release/623 (#1236) 2024-04-25 15:26:09 -07:00
Variant.test.cpp Sync to upstream/release/552 (#735) 2022-11-04 10:33:22 -07:00
VecDeque.test.cpp Sync to upstream/release/612 (#1162) 2024-02-09 09:51:12 -08:00
VisitType.test.cpp Sync to upstream/release/605 (#1118) 2023-12-01 23:46:57 -08:00