From 7ea0e456537294a4de74775ba7b7517337f28f1f Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 12 Jul 2022 01:33:50 -0600 Subject: [PATCH] Reduce GC on measureText --- packages/core/util/Base1DUtils.ts | 13 ++--- packages/core/util/Base1DViewModel.ts | 79 +-------------------------- packages/core/util/index.ts | 20 +++---- 3 files changed, 18 insertions(+), 94 deletions(-) diff --git a/packages/core/util/Base1DUtils.ts b/packages/core/util/Base1DUtils.ts index f97bdd7a32..da7b1cc91c 100644 --- a/packages/core/util/Base1DUtils.ts +++ b/packages/core/util/Base1DUtils.ts @@ -71,8 +71,9 @@ export function pxToBp(self: any, px: number) { offsetPx, displayedRegions, interRegionPaddingWidth, - staticBlocks: { blocks }, + staticBlocks, } = self + const blocks = staticBlocks.contentBlocks const bp = (offsetPx + px) * bpPerPx if (bp < 0) { const region = displayedRegions[0] @@ -90,8 +91,7 @@ export function pxToBp(self: any, px: number) { } const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx - let firstBlock = true - let currStaticBlock = blocks[0]?.regionNumber + let currBlock = 0 for (let i = 0; i < displayedRegions.length; i++) { const region = displayedRegions[i] const len = region.end - region.start @@ -112,10 +112,9 @@ export function pxToBp(self: any, px: number) { // add the interRegionPaddingWidth if the boundary is in the screen e.g. in // a static block - if (currStaticBlock === i) { - bpSoFar += len + (firstBlock ? 0 : interRegionPaddingBp) - currStaticBlock++ - firstBlock = false + if (blocks[currBlock]?.regionNumber === i) { + bpSoFar += len + interRegionPaddingBp + currBlock++ } else { bpSoFar += len } diff --git a/packages/core/util/Base1DViewModel.ts b/packages/core/util/Base1DViewModel.ts index bb26450ded..930b85cba8 100644 --- a/packages/core/util/Base1DViewModel.ts +++ b/packages/core/util/Base1DViewModel.ts @@ -1,4 +1,4 @@ -import { types, cast, getSnapshot, Instance } from 'mobx-state-tree' +import { types, cast, Instance } from 'mobx-state-tree' import { clamp } from './index' import { Feature } from './simpleFeature' import { Region, ElementId } from './types/mst' @@ -63,82 +63,7 @@ const Base1DView = types }, pxToBp(px: number) { - let bpSoFar = 0 - const bp = (self.offsetPx + px) * self.bpPerPx - const n = self.displayedRegions.length - if (bp < 0) { - const region = self.displayedRegions[0] - const offset = bp - const snap = getSnapshot(region) - return { - ...(snap as Omit), - oob: true, - coord: region.reversed - ? Math.floor(region.end - offset) + 1 - : Math.floor(region.start + offset) + 1, - offset, - index: 0, - } - } - - const interRegionPaddingBp = self.interRegionPaddingWidth * self.bpPerPx - const minimumBlockBp = self.minimumBlockWidth * self.bpPerPx - - for (let index = 0; index < self.displayedRegions.length; index += 1) { - const region = self.displayedRegions[index] - const len = region.end - region.start - const offset = bp - bpSoFar - if (len + bpSoFar > bp && bpSoFar <= bp) { - const snap = getSnapshot(region) - return { - ...(snap as Omit), - oob: false, - offset, - coord: region.reversed - ? Math.floor(region.end - offset) + 1 - : Math.floor(region.start + offset) + 1, - index, - } - } - - // add the interRegionPaddingWidth if the boundary is in the screen - // e.g. offset>0 && offset minimumBlockBp && - offset / self.bpPerPx > 0 && - offset / self.bpPerPx < this.width - ) { - bpSoFar += len + interRegionPaddingBp - } else { - bpSoFar += len - } - } - - if (bp >= bpSoFar) { - const region = self.displayedRegions[n - 1] - const len = region.end - region.start - const offset = bp - bpSoFar + len - const snap = getSnapshot(region) - return { - ...(snap as Omit), - oob: true, - offset, - coord: region.reversed - ? Math.floor(region.end - offset) + 1 - : Math.floor(region.start + offset) + 1, - index: n - 1, - } - } - return { - coord: 0, - index: 0, - start: 0, - refName: '', - oob: true, - assemblyName: '', - offset: 0, - reversed: false, - } + return pxToBp(self, px) }, })) .views(self => ({ diff --git a/packages/core/util/index.ts b/packages/core/util/index.ts index 8920e3f5fc..c456c31054 100644 --- a/packages/core/util/index.ts +++ b/packages/core/util/index.ts @@ -883,19 +883,19 @@ export const rIC = : (cb: Function) => setTimeout(() => cb(), 1) : (cb: Function) => cb() +// prettier-ignore +const widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625] + // xref https://gist.github.com/tophtucker/62f93a4658387bb61e4510c37e2e97cf export function measureText(str: unknown, fontSize = 10) { - // prettier-ignore - const widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625] const avg = 0.5279276315789471 - return ( - String(str) - .split('') - .map(c => - c.charCodeAt(0) < widths.length ? widths[c.charCodeAt(0)] : avg, - ) - .reduce((cur, acc) => acc + cur, 0) * fontSize - ) + const s = String(str) + let total = 0 + for (let i = 0; i < s.length; i++) { + const code = s.charCodeAt(i) + total += widths[code] ?? avg + } + return total * fontSize } export const defaultStarts = ['ATG']