Skip to content

Instantly share code, notes, and snippets.

@Lonenso
Created August 4, 2023 01:10
Show Gist options
  • Save Lonenso/9863c325bfb1af997fcf11a9b8b71991 to your computer and use it in GitHub Desktop.
Save Lonenso/9863c325bfb1af997fcf11a9b8b71991 to your computer and use it in GitHub Desktop.
ipc benchmark
<p>Send / Receive payload using ArrayBuffer, see output in devtools.</p>
<button id='send'>Send payload to main</button>
<button id='receive'> Receive payload from main</button>
<script src="renderer.js"></script>
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
ipcMain.handle('foo', (e, data) => {
const _ = data;
});
mainWindow.webContents.openDevTools();
ijpcMain.handle('bar', (e, payload) => {
e.sender.send('baz', { payload, sent_at:Date.now()});
});
}
app.whenReady().then(() => {
createWindow()
})
{
"name": "furtive-climate-pinch-itjhh",
"productName": "furtive-climate-pinch-itjhh",
"description": "My Electron application description",
"keywords": [],
"main": "./main.js",
"version": "1.0.0",
"author": "peter.xie",
"scripts": {
"start": "electron ."
},
"dependencies": {},
"devDependencies": {
"electron": "20.0.1"
}
}
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('API', {
foo: (payload) => ipcRenderer.invoke('foo', payload),
bar: (payload) => ipcRenderer.invoke('bar', payload),
onBar: (callback) => ipcRenderer.on('baz', callback),
});
/**
* This file is loaded via the <script> tag in the index.html file and will
* be executed in the renderer process for that window. No Node.js APIs are
* available in this process because `nodeIntegration` is turned off and
* `contextIsolation` is turned on. Use the contextBridge API in `preload.js`
* to expose Node.js functionality from the main process.
*/
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getRandomString(length) {
const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let result = '';
for (let i = 0; i < length; i++) {
const randomIndex = getRandomInt(0, characters.length - 1);
result += characters.charAt(randomIndex);
}
return result;
}
function generatePayload2(count) {
const elems = [];
const generatedIds = new Set();
for (let i = 0; i < count; i++) {
let id;
do {
id = getRandomInt(100000, 999999).toString();
} while (generatedIds.has(id));
generatedIds.add(id);
const elem = {
id: id,
type: getRandomString(10),
status: getRandomInt(0, 1) === 0 ? 'Enabled' : 'Disabled',
firstName: getRandomString(5),
lastName: getRandomString(7),
email: getRandomString(8) + '@example.com',
extensionNumber: getRandomInt(1000, 9999).toString(),
account: {
id: getRandomInt(100000, 999999).toString(),
},
phoneNumbers: [
{
phoneNumber: '+1' + getRandomInt(1000000000, 9999999999).toString(),
type: 'VoiceFax',
formattedPhoneNumber: '+1' + getRandomInt(1000000000, 9999999999).toString(),
usageType: 'DirectNumber',
primary: getRandomInt(0, 1) === 0,
},
{
phoneNumber: '+1' + getRandomInt(1000000000, 9999999999).toString(),
type: 'VoiceFax',
formattedPhoneNumber: '+1' + getRandomInt(1000000000, 9999999999).toString(),
usageType: 'DirectNumber',
primary: getRandomInt(0, 1) === 0,
},
],
__md5: getRandomString(32),
};
elems.push(elem);
}
return elems;
}
function generatePayload(count) {
return Array.from({length: count}, (_, i) => ({
key: '0000000000000000000000000' + i,
value: (Math.random() * 100 | 0).toString()
}))
}
const rawPayload = generatePayload2(100000);
const jsonFn = (payload) => {
const start = Date.now();
const ret = JSON.stringify(payload);
const took = Date.now() - start;
console.log(`jsonFn, size: ${ret.length} took: ${took}`);
return ret;
};
const jsonPayload = jsonFn(rawPayload);
const stringBufferFn = (payload) => {
const start = Date.now();
const ret = new TextEncoder().encode(payload);
const took = Date.now() - start;
console.log(`bufferFn, size: ${ret.length}, took: ${took}`);
return ret;
}
const bufferPayload = stringBufferFn(jsonPayload);
async function send(name, payload) {
let start = Date.now();
await window.API["foo"](payload);
let took = Date.now() - start;
let mbPerSecond = payload.length / took / 1000
console.log(`[${name}] Send ${payload.length} took ${took}, speed: ${mbPerSecond.toFixed(2)}MB/s`);
}
document.querySelector('#send').addEventListener(('click'), async () => {
await send("rawPayload", rawPayload);
await send("jsonPayload", jsonPayload);
});
document.querySelector('#receive').addEventListener(('click'), () => {
// window.API["bar"](rawPayload);
window.API["bar"](jsonPayload);
});
window.API["onBar"]((event, payload) => {
const now = Date.now();
const mbPerSecond = payload.payload.length / (now - payload.sent_at) / 1000
console.log(`receive ${payload.payload.length} took ${now - payload.sent_at}, speed: ${mbPerSecond}MB/s`)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment