-
Notifications
You must be signed in to change notification settings - Fork 224
perf: element event batch triggering #2005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
776071c
perf: element event batch triggering
wang1212 58f02e6
chore: update test snapshot
wang1212 2f29485
chore: use Array.from to convert iterator for compatibility
wang1212 8d017fc
chore: add changeset
wang1212 bb9d351
Update __tests__/demos/perf/custom-event.ts
wang1212 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| '@antv/g-plugin-canvaskit-renderer': minor | ||
| '@antv/g-plugin-canvas-renderer': minor | ||
| '@antv/g-plugin-device-renderer': minor | ||
| '@antv/g-plugin-html-renderer': minor | ||
| '@antv/g-plugin-image-loader': minor | ||
| '@antv/g-plugin-svg-renderer': minor | ||
| '@antv/g-plugin-a11y': minor | ||
| '@antv/g-plugin-yoga': minor | ||
| '@antv/g-lite': minor | ||
| --- | ||
|
|
||
| perf: element event batch triggering |
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| export interface BenchmarkResult { | ||
| [key: string]: string | number; | ||
| } | ||
|
|
||
| export class BenchmarkPanel { | ||
| private container: HTMLDivElement; | ||
| private title: string; | ||
| private configInfo: string | null = null; | ||
|
|
||
| constructor(title: string) { | ||
| this.title = title; | ||
|
|
||
| // Create result container on page | ||
| this.container = document.createElement('div'); | ||
| this.container.style.position = 'absolute'; | ||
| this.container.style.bottom = '10px'; | ||
| this.container.style.left = '10px'; | ||
| this.container.style.backgroundColor = 'rgba(0,0,0,0.8)'; | ||
| this.container.style.color = 'white'; | ||
| this.container.style.padding = '10px'; | ||
| this.container.style.borderRadius = '4px'; | ||
| this.container.style.fontFamily = 'monospace'; | ||
| this.container.style.fontSize = '12px'; | ||
| this.container.style.zIndex = '1000'; | ||
| this.container.style.maxWidth = '500px'; | ||
| this.container.id = 'benchmark-results-panel'; | ||
|
|
||
| document.body.appendChild(this.container); | ||
|
|
||
| // Show initial status | ||
| this.showRunningStatus(); | ||
| } | ||
|
|
||
| showRunningStatus(configInfo?: string) { | ||
| // Store config info for later use in updateResultsDisplay | ||
| this.configInfo = configInfo || null; | ||
|
|
||
| this.container.innerHTML = ` | ||
| <h3>${this.title}</h3> | ||
| ${configInfo ? `<div>${configInfo}</div><hr />` : ''} | ||
| <div>Running benchmark tests... Please wait.</div> | ||
| `; | ||
| } | ||
|
|
||
| updateResultsDisplay(results: BenchmarkResult[]) { | ||
| // Debug: log the actual structure of results | ||
| console.log('Benchmark results structure:', results); | ||
|
|
||
| // Generate table dynamically based on the keys in the first result | ||
| let tableHtml = | ||
| '<table style="width:100%; border-collapse: collapse; margin: 10px 0;">'; | ||
| tableHtml += '<thead><tr style="background-color: #333;">'; | ||
|
|
||
| if (results && results.length > 0) { | ||
| const firstResult = results[0]; | ||
| Object.keys(firstResult).forEach((key) => { | ||
| tableHtml += `<th style="border: 1px solid #666; padding: 4px; text-align: left;">${key}</th>`; | ||
| }); | ||
| } | ||
|
|
||
| tableHtml += '</tr></thead><tbody>'; | ||
|
|
||
| if (results && results.length > 0) { | ||
| // Create table rows for each result | ||
| results.forEach((result, index) => { | ||
| // Alternate row colors | ||
| const bgColor = | ||
| index % 2 === 0 ? 'rgba(50, 50, 50, 0.3)' : 'rgba(70, 70, 70, 0.3)'; | ||
| tableHtml += `<tr style="background-color: ${bgColor};">`; | ||
|
|
||
| Object.keys(result).forEach((key) => { | ||
| const value = result[key]; | ||
| tableHtml += `<td style="border: 1px solid #666; padding: 4px;">${value}</td>`; | ||
| }); | ||
|
|
||
| tableHtml += '</tr>'; | ||
| }); | ||
| } else { | ||
| tableHtml += '<tr><td colspan="3">No results available</td></tr>'; | ||
wang1212 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| tableHtml += '</tbody></table>'; | ||
|
|
||
| this.container.innerHTML = ` | ||
| <h3>${this.title}</h3> | ||
| ${this.configInfo ? `<div>${this.configInfo}</div><hr />` : ''} | ||
| ${tableHtml} | ||
| `; | ||
| } | ||
| } | ||
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| import { Canvas, ElementEvent, Rect, Group, CustomEvent } from '@antv/g'; | ||
| import * as tinybench from 'tinybench'; | ||
| import * as lil from 'lil-gui'; | ||
| import { BenchmarkPanel, BenchmarkResult } from './benchmark-panel'; | ||
|
|
||
| /** | ||
| * Custom Event Performance Test | ||
| * Compare performance between sharing a single event instance and creating new event instances each time | ||
| */ | ||
| export async function customEvent(context: { canvas: Canvas; gui: lil.GUI }) { | ||
| const { canvas, gui } = context; | ||
| console.log(canvas); | ||
|
|
||
| await canvas.ready; | ||
|
|
||
| const { width, height } = canvas.getConfig(); | ||
| const root = new Group(); | ||
| let count = 1e4; | ||
| let rects: { x: number; y: number; size: number; el: Rect }[] = []; | ||
|
|
||
| // Shared event instance | ||
| const sharedEvent = new CustomEvent(ElementEvent.BOUNDS_CHANGED); | ||
|
|
||
| function render() { | ||
| root.destroyChildren(); | ||
| rects = []; | ||
|
|
||
| for (let i = 0; i < count; i++) { | ||
| const x = Math.random() * width; | ||
| const y = Math.random() * height; | ||
| const size = 10 + Math.random() * 40; | ||
|
|
||
| const rect = new Rect({ | ||
| style: { | ||
| x, | ||
| y, | ||
| width: size, | ||
| height: size, | ||
| fill: 'white', | ||
| stroke: '#000', | ||
| lineWidth: 1, | ||
| }, | ||
| }); | ||
| root.appendChild(rect); | ||
| rects[i] = { x, y, size, el: rect }; | ||
| } | ||
| } | ||
|
|
||
| render(); | ||
| canvas.appendChild(root); | ||
|
|
||
| // benchmark | ||
| // ---------- | ||
| const bench = new tinybench.Bench({ | ||
| name: 'Custom Event Performance Comparison', | ||
| time: 1e3, | ||
| iterations: 100, | ||
| }); | ||
|
|
||
| // Test performance of shared event instance | ||
| // Update event properties each time to simulate realistic usage | ||
| bench.add('Shared Event Instance', () => { | ||
| rects.forEach((rect) => { | ||
| // Update event properties to simulate realistic usage | ||
| sharedEvent.detail = { | ||
| affectChildren: true, | ||
| timestamp: performance.now(), | ||
| }; | ||
| rect.el.dispatchEvent(sharedEvent); | ||
| }); | ||
| }); | ||
|
|
||
| // Test performance of creating new event instances each time | ||
| bench.add('New Event Instance', () => { | ||
| rects.forEach((rect) => { | ||
| const event = new CustomEvent(ElementEvent.BOUNDS_CHANGED); | ||
| event.detail = { | ||
| affectChildren: true, | ||
| timestamp: performance.now(), | ||
| }; | ||
| rect.el.dispatchEvent(event); | ||
| }); | ||
| }); | ||
|
|
||
| // Test performance of creating same number of events but dispatching only once on root | ||
| bench.add('Create Events, Dispatch Once on Root', () => { | ||
| const events = []; | ||
| // Create same number of event instances | ||
| for (let i = 0; i < count; i++) { | ||
| const event = new CustomEvent(ElementEvent.BOUNDS_CHANGED); | ||
| event.detail = { | ||
| affectChildren: true, | ||
| timestamp: performance.now(), | ||
| }; | ||
| events.push(event); | ||
| } | ||
| // But dispatch only once on root | ||
| root.dispatchEvent(events[0]); | ||
| }); | ||
|
|
||
| // Test performance of dispatching event on each element without sharing event instance | ||
| bench.add('Dispatch on Each Element', () => { | ||
| rects.forEach((rect) => { | ||
| const event = new CustomEvent(ElementEvent.BOUNDS_CHANGED); | ||
| event.detail = { | ||
| affectChildren: true, | ||
| timestamp: performance.now(), | ||
| }; | ||
| rect.el.dispatchEvent(event); | ||
| }); | ||
| }); | ||
wang1212 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Create benchmark panel | ||
| const benchmarkPanel = new BenchmarkPanel(bench.name); | ||
|
|
||
| // Show initial status with object count | ||
| benchmarkPanel.showRunningStatus(`Object Count: ${count}`); | ||
|
|
||
| // ---------- | ||
|
|
||
| // GUI | ||
| const config = { | ||
| objectCount: count, | ||
| runBenchmark: async () => { | ||
| benchmarkPanel.showRunningStatus(`Object Count: ${count}`); | ||
|
|
||
| setTimeout(async () => { | ||
| await bench.run(); | ||
| console.log(bench.name); | ||
| console.table(bench.table()); | ||
|
|
||
| benchmarkPanel.updateResultsDisplay( | ||
| bench.table() as unknown as BenchmarkResult[], | ||
| ); | ||
| }, 1e2); | ||
| }, | ||
| }; | ||
|
|
||
| gui.add(config, 'objectCount', 100, 50000, 100).onChange((value) => { | ||
| count = value; | ||
| render(); | ||
| }); | ||
|
|
||
| gui.add(config, 'runBenchmark'); | ||
| } | ||
This file contains hidden or 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
This file contains hidden or 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or 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
This file contains hidden or 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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.