Skip to content

Commit

Permalink
Clean up autotrackMemoize
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed May 10, 2023
1 parent ca25a77 commit 7efdeea
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 205 deletions.
19 changes: 0 additions & 19 deletions src/autotrackMemoize/autotrackMemoize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
export function autotrackMemoize<F extends (...args: any[]) => any>(func: F) {
// we reference arguments instead of spreading them for performance reasons

// console.log('Creating autotrack memoizer node')
const node: Node<Record<string, unknown>> = createNode(
[] as unknown as Record<string, unknown>
)
Expand All @@ -19,34 +18,16 @@ export function autotrackMemoize<F extends (...args: any[]) => any>(func: F) {

const shallowEqual = createCacheKeyComparator(defaultEqualityCheck)

// console.log('Creating cache')
const cache = createCache(() => {
// console.log('Executing cache: ', node.value)
const res = func.apply(null, node.proxy as unknown as any[])
// console.log('Res: ', res)
return res
})

// console.log('Creating memoized function')
function memoized() {
// console.log('Memoized running')
if (!shallowEqual(lastArgs, arguments)) {
// console.log(
// 'Args are different: lastArgs =',
// lastArgs,
// 'newArgs =',
// arguments
// )
updateNode(node, arguments as unknown as Record<string, unknown>)
lastArgs = arguments
} else {
// console.log('Same args: ', lastArgs, arguments)
}
// const start = performance.now()
// console.log('Calling memoized: ', arguments)

// const end = performance.now()
// console.log('Memoized execution time: ', end - start)
return cache.value
}

Expand Down
15 changes: 1 addition & 14 deletions src/autotrackMemoize/autotracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ export class Cell<T> {
_isEqual: EqualityFn = tripleEq

constructor(initialValue: T, isEqual: EqualityFn = tripleEq) {
// console.log('Constructing cell: ', initialValue)
this._value = this._lastValue = initialValue
this._isEqual = isEqual
}

// Whenever a storage value is read, it'll add itself to the current tracker if
// one exists, entangling its state with that cache.
get value() {
// console.log('Getting cell value: ', this._value)
CURRENT_TRACKER?.add(this)

return this._value
Expand All @@ -39,12 +37,10 @@ export class Cell<T> {
// based. We don't actively tell the caches which depend on the storage that
// anything has happened. Instead, we recompute the caches when needed.
set value(newValue) {
// console.log('Setting value: ', this.value, newValue)
// if (this.value === newValue) return
if (this.value === newValue) return

this._value = newValue
this.revision = ++$REVISION
// scheduleRerender()
}
}

Expand Down Expand Up @@ -138,16 +134,7 @@ export function setValue<T extends Cell<unknown>>(
'setValue must be passed a tracked store created with `createStorage`.'
)

// console.log('setValue: ', storage, value)

// console.log('Setting value: ', storage.value, value)
// storage.value = value

const { _isEqual: isEqual, _lastValue: lastValue } = storage

// if (!isEqual(value, lastValue)) {
storage.value = storage._lastValue = value
// }
}

export function createCell<T = unknown>(
Expand Down
152 changes: 2 additions & 150 deletions src/autotrackMemoize/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
// import { DEBUG } from '@glimmer/env'

// import { consumeTag, createTag, dirtyTag, Tag } from '@glimmer/validator'
// import { consumeTag, createTag, dirtyTag, Tag } from '../tracked-storage'
import { formatMs, logLater } from './utils'
import {
consumeCollection,
dirtyCollection,
Expand All @@ -28,33 +23,17 @@ class ObjectTreeNode<T extends Record<string, unknown>> implements Node<T> {
id = nextId++

constructor(public value: T) {
// console.log('Object node: ', this.value)
this.value = value
this.tag.value = value
}
}

const objectProxyHandler = {
get(node: Node, key: string | symbol): unknown {
// if (DEBUG && key === REDUX_PROXY_LABEL) {
// // logLater('Bailing out of getter: ', key)
// return true
// }
// let res : unknown;

const keyString = key.toString()
// if (keyString === 'constructor') {
// console.log('Constructor: ', node)
// }
const start = performance.now()

function calculateResult() {
// try {
const { value } = node

// console.time('Reflect.get: ' + keyString)
const childValue = Reflect.get(value, key)
// console.timeEnd('Reflect.get: ' + keyString)

if (typeof key === 'symbol') {
return childValue
Expand All @@ -65,55 +44,31 @@ const objectProxyHandler = {
}

if (typeof childValue === 'object' && childValue !== null) {
// logLater('Getting child node: ', key, childValue)
let childNode = node.children[key]

if (childNode === undefined) {
// console.time('Creating child node')

// console.log('Creating node: ', key, childValue)
childNode = node.children[key] = createNode(childValue)
// console.timeEnd('Creating child node')
}

if (childNode.tag) {
// logLater('Consuming tag: ', childNode)
// console.time('Consuming tag A: ' + keyString)
// console.log('Consuming tag: ', keyString)
consumeTag(childNode.tag)
// console.timeEnd('Consuming tag A: ' + keyString)
}

return childNode.proxy
} else {
let tag = node.tags[key]
if (key === 'constructor') {
// console.log('Constructor tag: ', tag)
}

if (tag === undefined) {
// console.time('Creating tag: ' + key)
// console.log('Creating tag: ', key)
tag = node.tags[key] = createTag()
// console.timeEnd('Creating tag: ' + key)
// console.time('Assigning tag value: ' + keyString)
tag.value = childValue
// console.timeEnd('Assigning tag value: ' + keyString)
}

// console.time('Consuming tag B: ' + keyString)
// console.log('Consuming tag: ', keyString, tag)
consumeTag(tag)

// console.timeEnd('Consuming tag B: ' + keyString)

return childValue
}
}
const res = calculateResult()

const end = performance.now()
// logLater(`Proxy get trap: ${keyString}: ${formatMs(end - start)}`)
return res
},

Expand All @@ -126,7 +81,6 @@ const objectProxyHandler = {
node: Node,
prop: string | symbol
): PropertyDescriptor | undefined {
console.log('getOwnPropertyDescriptor', prop)
return Reflect.getOwnPropertyDescriptor(node.value, prop)
},

Expand All @@ -144,7 +98,6 @@ class ArrayTreeNode<T extends Array<unknown>> implements Node<T> {
id = nextId++

constructor(public value: T) {
// console.log('Array node: ', value)
this.value = value
this.tag.value = value
}
Expand Down Expand Up @@ -194,14 +147,10 @@ export function updateNode<T extends Array<unknown> | Record<string, unknown>>(
node: Node<T>,
newValue: T
): void {
// console.log('UpdateNode: ', newValue)
const { value, tags, children } = node

node.value = newValue

const start = performance.now()

// console.time('updateNode: array check: ' + node.id)
if (
Array.isArray(value) &&
Array.isArray(newValue) &&
Expand All @@ -214,8 +163,6 @@ export function updateNode<T extends Array<unknown> | Record<string, unknown>>(
let newKeysSize = 0
let anyKeysAdded = false

// console.log('Key check: ', value, newValue)

for (const _key in value) {
oldKeysSize++
}
Expand All @@ -228,82 +175,19 @@ export function updateNode<T extends Array<unknown> | Record<string, unknown>>(
}
}

// let oldKeys = keysMap.get(value)
// if (!oldKeys) {
// oldKeys = new Set<string>()
// for (let key in value) {
// oldKeys.add(key)
// }
// keysMap.set(value, oldKeys)
// }
// oldKeyIteration = performance.now()
// let newKeys = keysMap.get(newValue)
// if (!newKeys) {
// newKeys = new Set<string>()
// for (let key in newValue) {
// newKeys.add(key)
// }
// keysMap.set(newValue, newKeys)
// }
// newKeyIteration = performance.now()
// // const oldKeys = Object.keys(value)
// // const newKeys = Object.keys(newValue)
// const isDifferent =
// oldKeys.size !== newKeys.size || anyKeysDifferent(oldKeys, newKeys)

const isDifferent = anyKeysAdded || oldKeysSize !== newKeysSize

if (
isDifferent
// [...oldKeys].some((k) => !newKeys!.has(k))
) {
// console.log('Dirtying collection: ', node)
if (isDifferent) {
dirtyCollection(node)
}
}
// console.time('Checking object keys')
// let oldKeys = keysMap.get(value)
// if (!oldKeys) {
// oldKeys = new Set<string>()
// for (const key in value) {
// oldKeys.add(key)
// }
// keysMap.set(value, oldKeys)
// }
// let newKeys = keysMap.get(value)
// if (!newKeys) {
// newKeys = new Set<string>()
// for (const key in newValue) {
// newKeys.add(key)
// }
// keysMap.set(newValue, newKeys)
// }
// // const oldKeys = Object.keys(value)
// // const newKeys = Object.keys(newValue)

// if (
// oldKeys.size !== newKeys.size ||
// [...oldKeys].some(k => !newKeys!.has(k))
// ) {
// dirtyCollection(node)
// }
// console.timeEnd('Checking object keys')
}

const arrayDone = performance.now()

// console.timeEnd('updateNode: array check: ' + node.id)

// console.time('updateNode: tags check: ' + node.id)

// console.log('Tags: ', tags)
for (const key in tags) {
// logLater('Tag key: ', key)
const childValue = (value as Record<string, unknown>)[key]
const newChildValue = (newValue as Record<string, unknown>)[key]

if (childValue !== newChildValue) {
// console.log('Dirtying tag: ', { key, childValue, newChildValue })
dirtyCollection(node)
dirtyTag(tags[key], newChildValue)
}
Expand All @@ -313,51 +197,21 @@ export function updateNode<T extends Array<unknown> | Record<string, unknown>>(
}
}

const tagsDone = performance.now()

// console.timeEnd('updateNode: tags check: ' + node.id)

// console.time('updateNode: keys check: ' + node.id)

for (const key in children) {
// logLater('Child key: ', key)
const childNode = children[key]
const newChildValue = (newValue as Record<string, unknown>)[key]

const childValue = childNode.value

if (childValue === newChildValue) {
// logLater('Skipping child node: ', key, childValue, newChildValue)
continue
} else if (
typeof newChildValue === 'object' &&
newChildValue !== null // &&
// Object.getPrototypeOf(newChildValue) === Object.getPrototypeOf(childValue)
) {
// logLater('Updating child node: ', key, childValue, newChildValue)
// console.time('Nested updateNode: ' + key)
} else if (typeof newChildValue === 'object' && newChildValue !== null) {
updateNode(childNode, newChildValue as Record<string, unknown>)
// console.timeEnd('Nested updateNode: ' + key)
} else {
deleteNode(childNode)
delete children[key]
}
}

const keysDone = performance.now()

// logLater(
// 'updateNode: ',
// {
// total: formatMs(keysDone - start),
// array: formatMs(arrayDone - start),
// tags: formatMs(tagsDone - arrayDone),
// keys: formatMs(keysDone - tagsDone)
// },
// node.value
// )

// console.timeEnd('updateNode: keys check: ' + node.id)
}

function deleteNode(node: Node): void {
Expand All @@ -371,6 +225,4 @@ function deleteNode(node: Node): void {
for (const key in node.children) {
deleteNode(node.children[key])
}
// Object.values(node.tags).map(dirtyTag)
// Object.values(node.children).map(deleteNode)
}
Loading

0 comments on commit 7efdeea

Please sign in to comment.