Merge pull request #39 from e-neighborhood-watch/master

Replace String.join
This commit is contained in:
Matthew Griffith 2021-04-16 08:48:22 -04:00 committed by GitHub
commit 458e078658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 0 deletions

View File

@ -459,3 +459,13 @@ It's pretty common to put things in a tuple (or threeple) to start a case statem
```
We could skip allocating the tuple though.
# String Joining
For joining (and concating) strings, Elm uses Javascript's Array join method after converting the list into a Javascript array.
We can replace this implementation with a faster one that traverses the list and builds the string through concatenation instead.
## Results Summary
* Not included in elm-optimize-level-2 tool
* The implementation used is similar to the improved String.join implementation [here](https://gitlab.com/e-neighborhood-watch/elm-string-benchmarks/#stringjoin) which sees some serious improvements over Elm's normal String.join.

View File

@ -23,6 +23,7 @@ import { createPassUnwrappedFunctionsTransformer } from './transforms/passUnwrap
import { replaceVDomNode } from './transforms/adjustVirtualDom';
import { inlineNumberToString } from './transforms/inlineNumberToString';
import { replaceListFunctions } from './transforms/replaceListFunctions';
import { replaceStringFunctions } from './transforms/replaceStringFunctions';
import { reportFunctionStatusInBenchmarks, v8Debug } from './transforms/analyze';
export type Options = {
@ -80,6 +81,7 @@ export const transform = async (
let inlineCtx: InlineContext | undefined;
const transformations: any[] = removeDisabled([
[transforms.replaceListFunctions, replaceListFunctions],
[transforms.replaceStringFunctions, replaceStringFunctions],
[transforms.v8Analysis, v8Debug],
[transforms.variantShapes, normalizeVariantShapes],

View File

@ -0,0 +1,40 @@
import ts, { isIdentifier } from 'typescript';
import { ast } from './utils/create';
const $elm$core$String$join = `
var $elm$core$String$join = F2(function (sep, strs) {
if (!strs.b) {
return "";
}
var acc = strs.a;
strs = strs.b;
for (; strs.b; strs = strs.b) {
acc = acc + sep + strs.a;
}
return acc;
};
`;
const replacements = {
$elm$core$String$join,
};
export const replaceStringFunctions: ts.TransformerFactory<ts.SourceFile> = (
context
) => (sourceFile) => {
const visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
if (ts.isVariableStatement(node)) {
const name = node.declarationList.declarations[0]?.name;
if (isIdentifier(name) && name.text in replacements) {
const key = name.text as keyof typeof replacements;
return ast(replacements[key]);
}
}
return ts.visitEachChild(node, visitor, context);
};
return ts.visitNode(sourceFile, visitor);
};

View File

@ -35,6 +35,7 @@ export type Transforms = {
objectUpdate: ObjectUpdate | false;
unusedValues: boolean;
replaceListFunctions: boolean;
replaceStringFunctions: boolean;
v8Analysis: boolean;
};
@ -77,5 +78,6 @@ export const toolDefaults: Transforms = {
objectUpdate: false,
unusedValues: false,
replaceListFunctions: false,
replaceStringFunctions: false,
v8Analysis: false
};