forked from expo/expo
-
Notifications
You must be signed in to change notification settings - Fork 0
Added performence tests to Blob #12
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
45 commits
Select commit
Hold shift + click to select a range
b53a3a4
Added test suites: Array Buffer, Bytes, constructor-endings, construc…
HubertBer e5e7869
in worker & slice tests
HubertBer 517def1
constructor dom windows + stream related tests
HubertBer 7e847a9
stream tests
HubertBer 47da557
slice fixes
HubertBer e80c2e0
Array buffer semi-fix, null type fix, byte offset fix
HubertBer 9a6d120
array buffer fix
HubertBer 440dbf6
removed android build files
HubertBer e90e2b3
Add link to the original tests on which the test suite is based
HubertBer 245c67a
bytes method fixed
HubertBer 5d0ce98
Blob typescript constructor changes
HubertBer 8c14ef2
options bugfixes
HubertBer a90cdcd
toString changed for ExpoBlob
HubertBer 7db8cd0
proper options handling
HubertBer cc73972
simpler constructor
HubertBer 04b80e8
TypeErrors proper handling & inapplicable DOM related tests removed
HubertBer 2eca68d
Frozen array test changed
HubertBer 9ab8021
stream fix
HubertBer f859acb
newline
HubertBer 0e5097c
constructor changes: different type checks, different mapping, differ…
HubertBer 218ca61
blob options fix
HubertBer 82e6c23
removed debug logs
HubertBer 416d3ca
found the proper way to iterate over blobParts in the constructor
HubertBer e9f98ba
small stream fix, removed todos and console logs
HubertBer ad49678
Merge branch 'main' into @HubertBer/android-blob-fixes
HubertBer 0499181
Changed Expo Blob length to match that of the default Blob
HubertBer bb7df98
stream fixed, removed todos (performing garbage collection in stream …
HubertBer 4e81b3d
removed debugging logs, added ts-expect-error where necessary, added …
HubertBer e9504c2
fixed some tests to be more inline with the wpt tests, removed syncTe…
HubertBer c726574
now throwing TypeError on invalid options.endings, refactor
HubertBer baf9902
documentation
HubertBer b8fc88e
unicode bugfix
HubertBer cc82774
test large slice start and end values
HubertBer cbef234
Merge branch 'main' into @HubertBer/android-blob-fixes
HubertBer 57323d9
performance test setup, first test
HubertBer b379d26
Added comparison
arturgesiarz 90d5702
Some changes
arturgesiarz d0bd5cd
Temp-commit
arturgesiarz 437fdee
Added new tests
arturgesiarz 7d8daf9
Added conversion to base64
arturgesiarz a9029ce
Edited basic test
arturgesiarz 4dc04be
Edited name BlobPerformanceTestScreen
arturgesiarz a73e711
BlobPerformanceScreen
arturgesiarz 8c6bef7
Merge with main
arturgesiarz a56ba46
BlobPerformenceTestScreen changes
arturgesiarz 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
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
287 changes: 287 additions & 0 deletions
287
apps/native-component-list/src/screens/Blob/expo-blob/BlobPerformanceTestScreen.tsx
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,287 @@ | ||
| import { Asset } from 'expo-asset'; | ||
| import { ExpoBlob } from 'expo-blob'; | ||
| import { useState } from 'react'; | ||
| import { View, Text, StyleSheet, Button, ScrollView } from 'react-native'; | ||
|
|
||
| import HeadingText from '../../../components/HeadingText'; | ||
| import MonoText from '../../../components/MonoText'; | ||
| import { Page } from '../../../components/Page'; | ||
|
|
||
| type PerformanceTestData = { | ||
| key: string; | ||
| blobOperation: () => Promise<number>; | ||
| expoBlobOperation: () => Promise<number>; | ||
| title: string; | ||
| iterations: number; | ||
| }; | ||
|
|
||
| function blobToBase64(blob: Blob) { | ||
| return new Promise<string>((resolve) => { | ||
| const reader = new FileReader(); | ||
| reader.onloadend = () => { | ||
| const result = reader.result; | ||
| if (typeof result === 'string') { | ||
| resolve(result); | ||
| } | ||
| }; | ||
| reader.readAsDataURL(blob); | ||
| }); | ||
| } | ||
|
|
||
| const performanceTest: PerformanceTestData[] = [ | ||
| { | ||
| key: 'basic-test', | ||
| blobOperation: async () => { | ||
| const T0 = performance.now(); | ||
| const blob = new Blob(['abcd'.repeat(50000)]); | ||
| blob.slice(0, 500000).slice(0, 50_000).slice(0, 40_000).slice(0, 30_000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| expoBlobOperation: async () => { | ||
| const T0 = performance.now(); | ||
| const blob = new ExpoBlob(['abcd'.repeat(50000)]); | ||
| blob.slice(0, 500000).slice(0, 50_000).slice(0, 40_000).slice(0, 30_000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| title: 'String Test', | ||
| iterations: 100, | ||
| }, | ||
| { | ||
| key: 'bmp-file-test', | ||
| blobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-2mb.bmp') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new Blob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| expoBlobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-2mb.bmp') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new ExpoBlob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| title: 'File Test (2MB BMP)', | ||
| iterations: 5, | ||
| }, | ||
| { | ||
| key: 'audio-file-test', | ||
| blobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-1mb.mp3') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new Blob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| expoBlobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-1mb.mp3') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new ExpoBlob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| title: 'File Test (1MB Audio)', | ||
| iterations: 25, | ||
| }, | ||
| { | ||
| key: 'video-file-test', | ||
| blobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-1mb.mp4') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new Blob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| expoBlobOperation: async () => { | ||
| const asset = Asset.fromModule( | ||
| require('../../../../assets/expo-blob/performance-test-1mb.mp4') | ||
| ); | ||
| await asset.downloadAsync(); | ||
| const uri = asset.localUri || asset.uri; | ||
| const response = await fetch(uri); | ||
| const blobResponse = await response.blob(); | ||
| const base64 = await blobToBase64(blobResponse); | ||
|
|
||
| const T0 = performance.now(); | ||
| const blob = new ExpoBlob([base64]); | ||
| blob.slice(0, 1000); | ||
| const T1 = performance.now(); | ||
| return T1 - T0; | ||
| }, | ||
| title: 'File Test (1MB Video)', | ||
| iterations: 25, | ||
| }, | ||
| ]; | ||
|
|
||
| type ArrayBufferExampleItemProps = { | ||
| example: PerformanceTestData; | ||
| result: { | ||
| blobTime: number; | ||
| expoBlobTime: number; | ||
| } | null; | ||
| onEvaluate: (example: PerformanceTestData) => void; | ||
| }; | ||
|
|
||
| function ArrayBufferExampleItem({ example, result, onEvaluate }: ArrayBufferExampleItemProps) { | ||
| let comparison = null; | ||
| if (result) { | ||
| const { blobTime, expoBlobTime } = result; | ||
| if (blobTime < expoBlobTime) { | ||
| const diff = expoBlobTime - blobTime; | ||
| const percent = (100 * diff) / expoBlobTime; | ||
| comparison = `Blob is ${percent.toFixed(6)}% (${diff.toFixed(6)} ms) faster`; | ||
| } else if (expoBlobTime < blobTime) { | ||
| const diff = blobTime - expoBlobTime; | ||
| const percent = (100 * diff) / blobTime; | ||
| comparison = `ExpoBlob is ${percent.toFixed(6)}% (${diff.toFixed(6)} ms) faster`; | ||
| } else { | ||
| comparison = 'Both are equally fast'; | ||
| } | ||
| } | ||
| return ( | ||
| <View> | ||
| <Text>{example.title}</Text> | ||
| <View> | ||
| {!result && <Button title="Evaluate" onPress={() => onEvaluate(example)} />} | ||
| {result && ( | ||
| <View> | ||
| <MonoText containerStyle={styles.resultContainer}> | ||
| <Text>Blob time: {result.blobTime.toFixed(6)} ms</Text> {'\n'} | ||
| <Text>Expo Blob time: {result.expoBlobTime.toFixed(6)} ms</Text> {'\n'} | ||
| <Text>{comparison}</Text> | ||
| </MonoText> | ||
| <Button title="Re-evaluate" onPress={() => onEvaluate(example)} /> | ||
| </View> | ||
| )} | ||
| </View> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| export default function BlobArrayBufferScreen() { | ||
| const [results, setResults] = useState<{ | ||
| [key: string]: { | ||
| blobTime: number; | ||
| expoBlobTime: number; | ||
| } | null; | ||
| }>({}); | ||
|
|
||
| const evaluatePerformanceTest = async (example: PerformanceTestData) => { | ||
| try { | ||
| let expoBlobTotal = 0; | ||
| let blobTotal = 0; | ||
| for (let i = 0; i < example.iterations; i++) { | ||
| expoBlobTotal += await example.expoBlobOperation(); | ||
| blobTotal += await example.blobOperation(); | ||
| } | ||
| setResults((prev) => ({ | ||
| ...prev, | ||
| [example.key]: { | ||
| blobTime: blobTotal / example.iterations, | ||
| expoBlobTime: expoBlobTotal / example.iterations, | ||
| }, | ||
| })); | ||
| } catch (error) { | ||
| console.error('Error in performance test', error); | ||
| setResults((prev) => ({ | ||
| ...prev, | ||
| [example.key]: null, | ||
| })); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <Page> | ||
| <ScrollView contentContainerStyle={styles.scrollContainer}> | ||
| <View style={styles.container}> | ||
| <HeadingText>Performance tests:</HeadingText> | ||
| <View style={styles.exmaplesContainer}> | ||
| {performanceTest.map((example) => ( | ||
| <ArrayBufferExampleItem | ||
| key={example.key} | ||
| example={example} | ||
| result={results[example.key]} | ||
| onEvaluate={evaluatePerformanceTest} | ||
| /> | ||
| ))} | ||
| </View> | ||
| </View> | ||
| </ScrollView> | ||
| </Page> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: {}, | ||
| scrollContainer: { | ||
| paddingBottom: 20, | ||
| }, | ||
| exmaplesContainer: { | ||
| marginTop: 10, | ||
| gap: 10, | ||
| }, | ||
| exampleContent: { | ||
| flexDirection: 'row', | ||
| }, | ||
| resultContainer: { | ||
| borderColor: '#229D2AFF', | ||
| padding: 10, | ||
| borderRadius: 5, | ||
| }, | ||
| iterationsInput: { | ||
| borderWidth: 1, | ||
| borderColor: '#ccc', | ||
| borderRadius: 4, | ||
| padding: 4, | ||
| minWidth: 60, | ||
| marginLeft: 8, | ||
| }, | ||
| }); | ||
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
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.