Skip to content

Instantly share code, notes, and snippets.

@slvrtrn

slvrtrn/App.tsx Secret

Created July 19, 2023 18:26
Show Gist options
  • Save slvrtrn/4588013222038c48cc2ad4ea6159e15e to your computer and use it in GitHub Desktop.
Save slvrtrn/4588013222038c48cc2ad4ea6159e15e to your computer and use it in GitHub Desktop.
Browser leaks test
import React, { useEffect } from 'react'
import logo from './logo.svg'
import './App.css'
import { memoryLeakSelects } from './Benchmark'
function App() {
useEffect(() => {
memoryLeakSelects()
}, [])
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
import { v4 as uuid_v4 } from 'uuid'
import { createClient } from '@clickhouse/client-browser'
const BATCH_SIZE = 100
const ITERATIONS = 100_000
export async function memoryInserts() {
const client = createClient({})
const tableName = `memory_leak_arrays_${uuid_v4().replace(/-/g, '')}`
await client.command({
query: `
CREATE TABLE ${tableName}
(
id UInt32,
data Array(String),
data2 Map(String, Array(String))
)
ENGINE MergeTree()
ORDER BY (id)
`,
clickhouse_settings: {
wait_end_of_query: 1,
},
})
console.info(`Created table ${tableName}`)
for (let i = 1; i <= ITERATIONS; i++) {
console.log(`Iteration ${i}`)
const values = makeRows()
await client.insert({
table: tableName,
format: 'JSONEachRow',
values,
})
}
console.log('Done')
}
export async function memoryLeakSelects() {
const client = createClient({})
let i = 0
while (i < 1000) {
console.log(`Iteration ${i}`)
const res = await client.query({
query: 'SELECT * FROM cell_towers',
format: 'JSONEachRow'
})
const reader = res.stream().getReader()
let count = 0
while (true) {
const { done, value } = await reader.read()
if (done) break
count += (value?.length ?? 0)
console.log(`Fetched ${count} so far`)
}
i++
}
}
function makeRows(): Row[] {
const batch = new Array(BATCH_SIZE)
for (let i = 0; i < BATCH_SIZE; i++) {
const data: Row['data'] = randomArray(randomInt(5, 10), randomStr)
const data2: Row['data2'] = {}
for (let i = 0; i < randomInt(5, 10); i++) {
data2[randomStr()] = randomArray(randomInt(5, 10), randomStr)
}
const row: Row = {
id: randomInt(1, 1000),
data,
data2,
}
batch.push(row)
}
return batch
}
interface Row {
id: number
data: string[]
data2: Record<string, string[]>
}
function randomStr() {
return Math.random().toString(36).slice(2)
}
function randomArray<T>(size: number, generator: () => T): T[] {
return Array.from({length: size}).map(() => generator())
}
function randomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min) + min);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment