Skip to content

Instantly share code, notes, and snippets.

@pero5ar
Created May 6, 2021 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pero5ar/422eaa5202dc0b5f221ba32156509d37 to your computer and use it in GitHub Desktop.
Save pero5ar/422eaa5202dc0b5f221ba32156509d37 to your computer and use it in GitHub Desktop.
// DB:
const getUsers = () => JSON.parse(
'[{"id":1,"name":"Maida Guyer"},{"id":2,"name":"Aadhav Hermanson"},{"id":3,"name":"Maddox Mccoy"},{"id":4,"name":"Dmitry Chesney"},{"id":5,"name":"Garen Garr"},{"id":6,"name":"Mckay Drum"},{"id":7,"name":"Lynleigh Haberman"},{"id":8,"name":"Maelie Kwong"},{"id":9,"name":"Anastasia Norman"},{"id":10,"name":"Amire Tullis"},{"id":11,"name":"Abdullahi Stinnett"},{"id":12,"name":"Araiya Colston"},{"id":13,"name":"Jett Tew"},{"id":14,"name":"Akira Adelman"},{"id":15,"name":"Mai Kahl"},{"id":16,"name":"Zaynah Hulbert"},{"id":17,"name":"Nana Firth"},{"id":18,"name":"Rozlyn Hudak"},{"id":19,"name":"Demetrios Schuck"},{"id":20,"name":"Rachel Hardy"},{"id":21,"name":"Clarity Prendergast"},{"id":22,"name":"Taylen Badillo"},{"id":23,"name":"Alesana Burdine"},{"id":24,"name":"Gweneth Mcgarvey"},{"id":25,"name":"Shai Siegfried"},{"id":26,"name":"Lizette Pastor"},{"id":27,"name":"Danielle Valencia"},{"id":28,"name":"Demarco Covert"},{"id":29,"name":"Kenya Major"},{"id":30,"name":"Meya Stolz"},{"id":31,"name":"Rick Chou"},{"id":32,"name":"Yahia Bibb"},{"id":33,"name":"Amiah Fenton"},{"id":34,"name":"Divina Bergmann"},{"id":35,"name":"Carlisle Bridgeman"},{"id":36,"name":"Jetson Murtha"},{"id":37,"name":"Morgan Brewer"},{"id":38,"name":"Jalayah Broderick"},{"id":39,"name":"Taliyah Dang"},{"id":40,"name":"Breanna Mcclellan"},{"id":41,"name":"Matheus Tabb"},{"id":42,"name":"Ariyah Kenney"},{"id":43,"name":"Lianna Gamboa"},{"id":44,"name":"Kassie Taber"},{"id":45,"name":"Nava Cupp"},{"id":46,"name":"Emsley Sasser"},{"id":47,"name":"Carina Solano"},{"id":48,"name":"Teagan Moody"},{"id":49,"name":"Yareli Root"},{"id":50,"name":"Anabel Culp"},{"id":51,"name":"Holley Oberg"},{"id":52,"name":"Xion Wardell"},{"id":53,"name":"Nicolo Stroman"},{"id":54,"name":"Lakelynn Avant"},{"id":55,"name":"Sarahi Washburn"},{"id":56,"name":"Emersen Kiel"},{"id":57,"name":"Kamryn Escobar"},{"id":58,"name":"Kalen Feller"},{"id":59,"name":"Emmilyn Keesee"},{"id":60,"name":"Melissa Holloway"},{"id":61,"name":"Kainan Nero"},{"id":62,"name":"Krislyn Gaspard"},{"id":63,"name":"Theresa Iverson"},{"id":64,"name":"Fabiana Bayless"},{"id":65,"name":"Kaydence Lefevre"},{"id":66,"name":"Amauri Broome"},{"id":67,"name":"Kirill Garretson"},{"id":68,"name":"Woodrow Hung"},{"id":69,"name":"Marelyn Kiss"},{"id":70,"name":"Evaluna Feathers"},{"id":71,"name":"Neil Lowry"},{"id":72,"name":"Lexy Whitehurst"},{"id":73,"name":"Zahara Cheney"},{"id":74,"name":"Theadora Chasteen"},{"id":75,"name":"Jaslene Ashe"},{"id":76,"name":"Elani Jurado"},{"id":77,"name":"Kristin Partridge"},{"id":78,"name":"Aziz Kesler"},{"id":79,"name":"Lexie Gee"},{"id":80,"name":"Tavion Billups"},{"id":81,"name":"Reniyah Bengtson"},{"id":82,"name":"Holton Cusick"},{"id":83,"name":"Jediah Markowski"},{"id":84,"name":"Breckyn Said"},{"id":85,"name":"Kaela Groh"},{"id":86,"name":"Mavis Wilkes"},{"id":87,"name":"Kacper Hersh"},{"id":88,"name":"Wynn Kuhns"},{"id":89,"name":"Aashvi Bristol"},{"id":90,"name":"Novalee Wetzel"},{"id":91,"name":"Aleyza Lampe"},{"id":92,"name":"Georgette Kucera"},{"id":93,"name":"Tylon Sutphin"},{"id":94,"name":"Ellarose Smock"},{"id":95,"name":"Posey Coulson"},{"id":96,"name":"Amberlyn Goto"},{"id":97,"name":"Kaizer Lawhorn"},{"id":98,"name":"Josey Schenk"},{"id":99,"name":"Quincey Bugg"},{"id":100,"name":"Sandro Cifuentes"}]'
);
function createDatabase() {
const MAX_PERSONAL_BOARDS = 5;
const MAX_WORKSPACE_BOARDS = 10;
const MAX_CARDS = 100;
const MAX_BOARD_USERS = 15;
const MAX_CARD_USERS = 5;
const users = getUsers();
const roles = ['GUEST', 'MEMBER', 'ADMIN'];
const type_labels = ['DESIGN', 'DEVELOPMENT', 'QA', 'RESEARCH', 'MANAGMENT', 'LEGAL'];
const statuses = ['SUGGESTION', 'TODO', 'IN_PROGRESS', 'PUSHING', 'TESTING', 'ACCEPTED', 'REJECTED', 'DONE'];
const priority_labels = ['HIGH_PRIORITY', 'LOW_PRIORITY', 'MEDIUM_PRIORITY', 'BLOCKING'];
let boardId = 0;
const allBoards = [];
let workspaceId = 0;
const allWorkspaces = [];
for (const _user of users) {
_user.personalWorkspaceBoards = [];
_user.workspaces = [];
// add boards to first user only:
if (_user !== users[0]) continue;
const noOfBoards = Math.ceil(Math.random() * MAX_PERSONAL_BOARDS);
for (let i = 0; i < noOfBoards; i++) {
const board = {
id: ++boardId,
name: Math.random().toString(36).substring(3),
owner: _user,
lists: statuses.map((_s) => ({ name: _s })),
boardUsers: [({ user: _user, role: 'ADMIN' })],
};
allBoards.push(board);
_user.personalWorkspaceBoards.push(board);
}
}
// add workspaces to first user only:
for (const name of type_labels) {
const workspaceOwner = users[0];
const workspace = {
id: ++workspaceId,
name,
owner: workspaceOwner,
boards: [],
};
allWorkspaces.push(workspace);
workspaceOwner.workspaces.push(workspace);
const noOfBoards = Math.ceil(Math.random() * MAX_WORKSPACE_BOARDS);
for (let i = 0; i < noOfBoards; i++) {
const boardOwner = users[Math.floor(Math.random() * users.length)];
const board = {
id: ++boardId,
name: 'board_' + Math.random().toString(36).substring(3),
owner: boardOwner,
lists: statuses.map((_s) => ({ name: _s })),
boardUsers: [({ user: boardOwner, role: 'ADMIN' })],
};
allBoards.push(board);
workspace.boards.push(board);
}
}
for (const _board of allBoards) {
const noOfBoardUsers = Math.ceil(Math.random() * MAX_BOARD_USERS);
for (let i = 0; i < noOfBoardUsers; i++) {
const user = users[Math.floor(Math.random() * users.length)];
if (_board.boardUsers.some((_boardUser) => _boardUser.user.id === user.id)) {
continue;
}
_board.boardUsers.push(({ user, role: roles[Math.floor(Math.random() * roles.length)] }));
}
for (const _list of _board.lists) {
_list.cards = [];
const noOfCards = Math.ceil(Math.random() * MAX_CARDS);
for (let i = 0; i < noOfCards; i++) {
const card = {
name: 'card_' + Math.random().toString(36).substring(3),
labels: [],
users: [],
};
_list.cards.push(card);
if (Math.random() > 0.5) card.labels.push(priority_labels[Math.floor(Math.random() * priority_labels.length)]);
if (Math.random() > 0.1) card.labels.push(type_labels[Math.floor(Math.random() * type_labels.length)]);
const noOfCardUsers = Math.ceil(Math.random() * MAX_CARD_USERS);
for (let j = 0; j < noOfCardUsers; j++) {
const user = users[Math.floor(Math.random() * users.length)];
if (card.users.some((_user) => _user.id === user.id)) {
continue;
}
card.users.push(user);
}
}
}
}
return ({ users, allBoards, allWorkspaces });
}
// Use cases:
function build_getDesigners_v1() {
return function getDesigners_v1(targetUser) {
return []
.concat(
[].concat(
...targetUser.personalWorkspaceBoards.map((_board) =>
[].concat(
..._board.lists.map((_list) =>
_list.cards
.filter((_card) =>
_card.labels.some((_label) => _label.name === 'DESIGN')
)
.map((_card) => _card.users)
)
)
)
),
[].concat(
...targetUser.workspaces
.find((_workspace) => _workspace.name === 'DESIGN')
.boards.map((_board) =>
_board.boardUsers
.filter((_boardUser) =>
['MEMBER', 'ADMIN'].includes(_boardUser.role)
)
.map((_boardUser) => _boardUser.user)
)
),
targetUser.workspaces
.find((_workspace) => _workspace.name === 'DESIGN')
.boards.map((_board) => _board.owner)
)
.filter(
(_user1, _index1, _array) =>
!_array.some(
(_user2, _index2) => _index1 > _index2 && _user1.id === _user2.id
)
);
}
}
function build_getDesigners_v2() {
// NOTE: improvment only came to shine when reduce was added
return function getDesigners_v2(targetUser) {
const designWorkspace = targetUser.workspaces.find((_workspace) => _workspace.name === 'DESIGN');
return []
.concat(
targetUser.personalWorkspaceBoards.flatMap((_board) =>
_board.lists.flatMap((_list) =>
_list.cards.reduce(
(_result, _card) => {
if (_card.labels.some((_label) => _label.name === 'DESIGN')) {
_result.push(_card.users);
}
return _result;
},
[]
)
)
),
designWorkspace.boards.flatMap((_board) =>
_board.boardUsers.reduce(
(_result, _boardUser) => {
if (['MEMBER', 'ADMIN'].includes(_boardUser.role)) {
_result.push(_boardUser.user)
}
return _result;
},
[]
)
),
designWorkspace.boards.map((_board) => _board.owner)
)
.filter(
(_user1, _index1, _array) =>
!_array.some(
(_user2, _index2) => _index1 > _index2 && _user1.id === _user2.id
)
);
}
}
function build_getDesigners_v3() {
const NON_GUEST_ROLES = ['MEMBER', 'ADMIN'];
const _isDesignLabel = (_label) => _label.name === 'DESIGN';
const _isDesignCard = (_card) => _card.labels.some(_isDesignLabel);
const _getCardUsers = (_card) => _card.users;
const _getDesignCardUsersFromList = (_list) => _list.cards.filter(_isDesignCard).map(_getCardUsers);
const _getDesignCardUsersFromBoard = (_board) => [].concat(..._board.lists.map(_getDesignCardUsersFromList));
const _isDesignWorkspace = (_workspace) => _workspace.name === 'DESIGN';
const _isNotGuest = (_boardUser) => NON_GUEST_ROLES.includes(_boardUser.role)
const _getBoardUserUser = (_boardUser) => _boardUser.user;
const _getNonGuestBoardUsers = (_board) => _board.boardUsers.filter(_isNotGuest).map(_getBoardUserUser)
const _getBoardUserOwner = (_board) => _board.owner;
const _filterDuplicates = (_user1, _index1, _array) => !_array.some((_user2, _index2) => _index1 > _index2 && _user1.id === _user2.id);
return function getDesigners_v3(targetUser) {
return []
.concat(
[].concat(
...targetUser.personalWorkspaceBoards.map(_getDesignCardUsersFromBoard)
),
[].concat(
...targetUser.workspaces
.find(_isDesignWorkspace)
.boards.map(_getNonGuestBoardUsers)
),
targetUser.workspaces
.find(_isDesignWorkspace)
.boards.map(_getBoardUserOwner)
)
.filter(_filterDuplicates);
}
}
function build_getDesigners_v4() {
const NON_GUEST_ROLES = ['MEMBER', 'ADMIN'];
const _isDesignLabel = (_label) => _label.name === 'DESIGN';
const _accumulateDesignCardUsers = (_result, _card) => {
if (_card.labels.some(_isDesignLabel)) {
_result.push(_card.users);
}
return _result;
}
const _mapListToAccumulatedNonDesignCardUsers = (_list) => _list.cards.reduce(_accumulateDesignCardUsers, []);
const _mapBoardToAccumulatedNonDesignCardUsers = (_board) => _board.lists.flatMap(_mapListToAccumulatedNonDesignCardUsers);
const _isDesignWorkspace = (_workspace) => _workspace.name === 'DESIGN';
const _accumulateNonGuestUsers = (_result, _boardUser) => {
if (NON_GUEST_ROLES.includes(_boardUser.role)) {
_result.push(_boardUser.user)
}
return _result;
}
const _mapBoardToAccumulatedNonGuestUsers = (_board) => _board.boardUsers.reduce(_accumulateNonGuestUsers, []);
const _getBoardUserOwner = (_board) => _board.owner;
const _filterDuplicates = (_user1, _index1, _array) => !_array.some((_user2, _index2) => _index1 > _index2 && _user1.id === _user2.id);
return function getDesigners_v4(targetUser) {
const designWorkspace = targetUser.workspaces.find(_isDesignWorkspace);
return []
.concat(
targetUser.personalWorkspaceBoards.flatMap(_mapBoardToAccumulatedNonDesignCardUsers),
designWorkspace.boards.flatMap(_mapBoardToAccumulatedNonGuestUsers),
designWorkspace.boards.map(_getBoardUserOwner)
)
.filter(_filterDuplicates);
}
}
// Helpers:
const getHeapUsedKBDiff = (m_start, m_end) => (m_end.heapUsed - m_start.heapUsed) / 1024;
// Main:
function test() {
const { performance } = require('perf_hooks');
const TEST_ITERATIONS = 10000;
const DB_SIZE = 100;
const db = [];
console.log('Creating dbs...')
for (let i = 0; i < DB_SIZE; i++) {
db[i] = createDatabase();
}
console.log('done!');
console.log('---------');
const results = [];
console.time('build_getDesigners_v1');
const build_getDesigners_v1_mem_start = process.memoryUsage();
const getDesigners_v1 = build_getDesigners_v1();
const build_getDesigners_v1_mem_end = process.memoryUsage();
console.timeEnd('build_getDesigners_v1');
console.info('build_getDesigners_v1 memory diff: ', getHeapUsedKBDiff(build_getDesigners_v1_mem_start, build_getDesigners_v1_mem_end));
console.time('build_getDesigners_v2');
const build_getDesigners_v2_mem_start = process.memoryUsage();
const getDesigners_v2 = build_getDesigners_v2();
const build_getDesigners_v2_mem_end = process.memoryUsage();
console.timeEnd('build_getDesigners_v2');
console.info('build_getDesigners_v2 memory diff: ', getHeapUsedKBDiff(build_getDesigners_v2_mem_start, build_getDesigners_v2_mem_end));
console.time('build_getDesigners_v3');
const build_getDesigners_v3_mem_start = process.memoryUsage();
const getDesigners_v3 = build_getDesigners_v3();
const build_getDesigners_v3_mem_end = process.memoryUsage();
console.timeEnd('build_getDesigners_v3');
console.info('build_getDesigners_v3 memory diff: ', getHeapUsedKBDiff(build_getDesigners_v3_mem_start, build_getDesigners_v3_mem_end));
console.time('build_getDesigners_v4');
const build_getDesigners_v4_mem_start = process.memoryUsage();
const getDesigners_v4 = build_getDesigners_v4();
const build_getDesigners_v4_mem_end = process.memoryUsage();
console.timeEnd('build_getDesigners_v4');
console.info('build_getDesigners_v4 memory diff: ', getHeapUsedKBDiff(build_getDesigners_v4_mem_start, build_getDesigners_v4_mem_end));
console.log('---------');
let getDesigners_v1_totalMemoryDiff = 0;
let getDesigners_v1_totalTimeDiff = 0;
let getDesigners_v1_gcRounds = 0;
console.time('getDesigners_v1');
for (let i = 0; i < TEST_ITERATIONS; i++) {
const user = { ...db[i % DB_SIZE].users[0] };
const getDesigners_v1_time_start = performance.now();
const getDesigners_v1_mem_start = process.memoryUsage();
results[0] = getDesigners_v1(user);
const getDesigners_v1_mem_end = process.memoryUsage();
const getDesigners_v1_time_end = performance.now();
const mem_diff = getHeapUsedKBDiff(getDesigners_v1_mem_start, getDesigners_v1_mem_end);
if (mem_diff < 0) {
getDesigners_v1_gcRounds++;
i--; // repeat computation
} else {
getDesigners_v1_totalMemoryDiff += mem_diff
getDesigners_v1_totalTimeDiff += (getDesigners_v1_time_end - getDesigners_v1_time_start);
}
}
console.timeEnd('getDesigners_v1');
console.info('getDesigners_v1 time diff: ', (getDesigners_v1_totalTimeDiff).toPrecision(3), ' ms');
console.info('getDesigners_v1 gc sweeps: ', getDesigners_v1_gcRounds);
console.info('getDesigners_v1 memory diff: ', Math.round(getDesigners_v1_totalMemoryDiff), ' KB');
const v1_c1 = Math.round(getDesigners_v1_totalTimeDiff * 1000) / 1000;
const v1_c2 = Math.round(getDesigners_v1_totalMemoryDiff);
console.log('---------');
let getDesigners_v2_totalMemoryDiff = 0;
let getDesigners_v2_totalTimeDiff = 0;
let getDesigners_v2_gcRounds = 0;
console.time('getDesigners_v2');
for (let i = 0; i < TEST_ITERATIONS; i++) {
const user = { ...db[i % DB_SIZE].users[0] };
const getDesigners_v2_time_start = performance.now();
const getDesigners_v2_mem_start = process.memoryUsage();
results[1] = getDesigners_v2(user);
const getDesigners_v2_mem_end = process.memoryUsage();
const getDesigners_v2_time_end = performance.now();
const mem_diff = getHeapUsedKBDiff(getDesigners_v2_mem_start, getDesigners_v2_mem_end);
if (mem_diff < 0) {
getDesigners_v2_gcRounds++;
i--; // repeat computation
} else {
getDesigners_v2_totalMemoryDiff += mem_diff
getDesigners_v2_totalTimeDiff += (getDesigners_v2_time_end - getDesigners_v2_time_start);
}
}
console.timeEnd('getDesigners_v2');
console.info('getDesigners_v2 time diff: ', (getDesigners_v2_totalTimeDiff).toPrecision(3), ' ms');
console.info('getDesigners_v2 gc sweeps: ', getDesigners_v2_gcRounds);
console.info('getDesigners_v2 memory diff: ', Math.round(getDesigners_v2_totalMemoryDiff), ' KB');
const v2_c1 = Math.round(getDesigners_v2_totalTimeDiff * 1000) / 1000;
const v2_c2 = Math.round(getDesigners_v2_totalMemoryDiff);
console.log('---------');
let getDesigners_v3_totalMemoryDiff = 0;
let getDesigners_v3_totalTimeDiff = 0;
let getDesigners_v3_gcRounds = 0;
console.time('getDesigners_v3');
for (let i = 0; i < TEST_ITERATIONS; i++) {
const user = { ...db[i % DB_SIZE].users[0] };
const getDesigners_v3_time_start = performance.now();
const getDesigners_v3_mem_start = process.memoryUsage();
results[2] = getDesigners_v3(user);
const getDesigners_v3_mem_end = process.memoryUsage();
const getDesigners_v3_time_end = performance.now();
const mem_diff = getHeapUsedKBDiff(getDesigners_v3_mem_start, getDesigners_v3_mem_end);
if (mem_diff < 0) {
getDesigners_v3_gcRounds++;
i--; // repeat computation
} else {
getDesigners_v3_totalMemoryDiff += mem_diff
getDesigners_v3_totalTimeDiff += (getDesigners_v3_time_end - getDesigners_v3_time_start);
}
}
console.timeEnd('getDesigners_v3');
console.info('getDesigners_v3 time diff: ', (getDesigners_v3_totalTimeDiff).toPrecision(3), ' ms');
console.info('getDesigners_v3 gc sweeps: ', getDesigners_v3_gcRounds);
console.info('getDesigners_v3 memory diff: ', Math.round(getDesigners_v3_totalMemoryDiff), ' KB');
const v3_c1 = Math.round(getDesigners_v3_totalTimeDiff * 1000) / 1000;
const v3_c2 = Math.round(getDesigners_v3_totalMemoryDiff);
console.log('---------');
let getDesigners_v4_totalMemoryDiff = 0;
let getDesigners_v4_totalTimeDiff = 0;
let getDesigners_v4_gcRounds = 0;
console.time('getDesigners_v4');
for (let i = 0; i < TEST_ITERATIONS; i++) {
const user = { ...db[i % DB_SIZE].users[0] };
const getDesigners_v4_time_start = performance.now();
const getDesigners_v4_mem_start = process.memoryUsage();
results[3] = getDesigners_v4(user);
const getDesigners_v4_mem_end = process.memoryUsage();
const getDesigners_v4_time_end = performance.now();
const mem_diff = getHeapUsedKBDiff(getDesigners_v4_mem_start, getDesigners_v4_mem_end);
if (mem_diff < 0) {
getDesigners_v4_gcRounds++;
i--; // repeat computation
} else {
getDesigners_v4_totalMemoryDiff += mem_diff
getDesigners_v4_totalTimeDiff += (getDesigners_v4_time_end - getDesigners_v4_time_start);
}
}
console.timeEnd('getDesigners_v4');
console.info('getDesigners_v4 time diff: ', (getDesigners_v4_totalTimeDiff).toPrecision(3), ' ms');
console.info('getDesigners_v4 gc sweeps: ', getDesigners_v4_gcRounds);
console.info('getDesigners_v4 memory diff: ', Math.round(getDesigners_v4_totalMemoryDiff), ' KB');
const v4_c1 = Math.round(getDesigners_v4_totalTimeDiff * 1000) / 1000;
const v4_c2 = Math.round(getDesigners_v4_totalMemoryDiff);
console.log('---------');
console.log('---------');
console.warn(`${TEST_ITERATIONS};${v1_c1};${v1_c2};${v2_c1};${v2_c2};${v3_c1};${v3_c2};${v4_c1};${v4_c2}`)
console.log('---------');
console.log('---------');
}
test();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment