-
-
Save slvrtrn/4588013222038c48cc2ad4ea6159e15e to your computer and use it in GitHub Desktop.
Browser leaks test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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