├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── MemoryPool.cpp ├── MemoryPool.h ├── README.md ├── benchmarks ├── CMakeLists.txt ├── STDString.cpp ├── STDString.h ├── String.cpp ├── String.h └── main.cpp ├── images ├── MacOS_Benchmark.png ├── Windows_Benchmark.png └── Windows_Benchmark_CLang.png └── tests ├── CMakeLists.txt ├── advanced_garbage_collection ├── CMakeLists.txt └── main.cpp ├── overriding_new_delete ├── CMakeLists.txt └── main.cpp ├── performance_mode ├── CMakeLists.txt └── main.cpp ├── simple_garbage_collection ├── CMakeLists.txt └── main.cpp └── thread_safety ├── CMakeLists.txt └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | */out/ 3 | /.vs* 4 | */CMakeSettings.json 5 | CMakeSettings.json 6 | /build 7 | .idea/ 8 | */cmake-build-* -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | sapir@devshift.biz. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /MemoryPool.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include "MemoryPool.h" 22 | #include 23 | 24 | AppShift::Memory::MemoryPool::MemoryPool(size_t block_size) 25 | { 26 | // Add first block to memory pool 27 | this->firstBlock = this->currentBlock = nullptr; 28 | this->defaultBlockSize = block_size; 29 | this->currentScope = nullptr; 30 | this->createMemoryBlock(block_size); 31 | } 32 | 33 | AppShift::Memory::MemoryPool::~MemoryPool() { 34 | SMemoryBlockHeader* block_iterator = firstBlock; 35 | 36 | while (block_iterator != nullptr) { 37 | SMemoryBlockHeader* next_iterator = block_iterator->next; 38 | std::free(block_iterator); 39 | block_iterator = next_iterator; 40 | } 41 | } 42 | 43 | void AppShift::Memory::MemoryPool::createMemoryBlock(size_t block_size) 44 | { 45 | // Create the block 46 | SMemoryBlockHeader* block = reinterpret_cast(std::malloc(sizeof(SMemoryBlockHeader) + block_size)); 47 | if (block == NULL) throw EMemoryErrors::CANNOT_CREATE_BLOCK; 48 | 49 | // Initalize block data 50 | block->blockSize = block_size; 51 | block->offset = 0; 52 | block->numberOfAllocated = 0; 53 | block->numberOfDeleted = 0; 54 | 55 | if (this->firstBlock != nullptr) { 56 | block->next = nullptr; 57 | block->prev = this->currentBlock; 58 | this->currentBlock->next = block; 59 | this->currentBlock = block; 60 | } 61 | else { 62 | block->next = block->prev = nullptr; 63 | this->firstBlock = block; 64 | this->currentBlock = block; 65 | } 66 | } 67 | 68 | void* AppShift::Memory::MemoryPool::allocate(size_t size) 69 | { 70 | // If there is enough space in current block then use the current block 71 | if (size + sizeof(SMemoryUnitHeader) < this->currentBlock->blockSize - this->currentBlock->offset); 72 | // Create new block if not enough space 73 | else if (size + sizeof(SMemoryUnitHeader) >= this->defaultBlockSize) this->createMemoryBlock(size + sizeof(SMemoryUnitHeader)); 74 | else this->createMemoryBlock(this->defaultBlockSize); 75 | 76 | // Add unit 77 | SMemoryUnitHeader* unit = reinterpret_cast(reinterpret_cast(this->currentBlock) + sizeof(SMemoryBlockHeader) + this->currentBlock->offset); 78 | unit->length = size; 79 | unit->container = this->currentBlock; 80 | this->currentBlock->numberOfAllocated++; 81 | this->currentBlock->offset += sizeof(SMemoryUnitHeader) + size; 82 | 83 | return reinterpret_cast(unit) + sizeof(SMemoryUnitHeader); 84 | } 85 | 86 | void* AppShift::Memory::MemoryPool::reallocate(void* unit_pointer_start, size_t new_size) 87 | { 88 | if (unit_pointer_start == NULL) return nullptr; 89 | 90 | // Find unit 91 | SMemoryUnitHeader* unit = reinterpret_cast(reinterpret_cast(unit_pointer_start) - sizeof(SMemoryUnitHeader)); 92 | SMemoryBlockHeader* block = unit->container; 93 | 94 | // If last in block && enough space in block, then reset length 95 | if (reinterpret_cast(block) + sizeof(SMemoryBlockHeader) + block->offset == reinterpret_cast(unit) + sizeof(SMemoryUnitHeader) + unit->length 96 | && block->blockSize > block->offset + new_size - unit->length) { 97 | block->offset += new_size - unit->length; 98 | unit->length = new_size; 99 | 100 | return unit_pointer_start; 101 | } 102 | 103 | // Allocate new and free previous 104 | void* temp_point = this->allocate(new_size); 105 | std::memcpy(temp_point, unit_pointer_start, unit->length); 106 | this->free(unit_pointer_start); 107 | 108 | return temp_point; 109 | } 110 | 111 | void AppShift::Memory::MemoryPool::free(void* unit_pointer_start) 112 | { 113 | if (unit_pointer_start == nullptr) return; 114 | 115 | // Find unit 116 | SMemoryUnitHeader* unit = reinterpret_cast(reinterpret_cast(unit_pointer_start) - sizeof(SMemoryUnitHeader)); 117 | SMemoryBlockHeader* block = unit->container; 118 | 119 | // If last in block, then reset offset 120 | if (reinterpret_cast(block) + sizeof(SMemoryBlockHeader) + block->offset == reinterpret_cast(unit) + sizeof(SMemoryUnitHeader) + unit->length) { 121 | block->offset -= sizeof(SMemoryUnitHeader) + unit->length; 122 | block->numberOfAllocated--; 123 | } 124 | else block->numberOfDeleted++; 125 | 126 | // If block offset is 0 remove block if not the only one left 127 | if (this->currentBlock != this->firstBlock && (block->offset == 0 || block->numberOfAllocated == block->numberOfDeleted)) { 128 | if (block == this->firstBlock) { 129 | this->firstBlock = block->next; 130 | this->firstBlock->prev = nullptr; 131 | } 132 | else if (block == this->currentBlock) { 133 | this->currentBlock = block->prev; 134 | this->currentBlock->next = nullptr; 135 | } 136 | else { 137 | block->prev->next = block->next; 138 | block->next->prev = block->prev; 139 | } 140 | std::free(block); 141 | } 142 | } 143 | 144 | 145 | void AppShift::Memory::MemoryPool::dumpPoolData() 146 | { 147 | SMemoryBlockHeader* block = this->firstBlock; 148 | SMemoryUnitHeader* unit; 149 | 150 | size_t current_unit_offset; 151 | size_t block_counter = 1; 152 | size_t unit_counter = 1; 153 | 154 | while (block != nullptr) { 155 | // Dump block data 156 | std::cout << "Block " << block_counter << ": " << std::endl; 157 | std::cout << "\t" << "Used: " << (float)(block->offset) / (float)(block->blockSize) * 100 << "% " << "(" << block->offset << "/" << block->blockSize << ")" << std::endl; 158 | 159 | if (block->offset == 0) { 160 | block = block->next; 161 | block_counter++; 162 | continue; 163 | } 164 | 165 | std::cout << "\t" << "Units: ========================" << std::endl; 166 | current_unit_offset = 0; 167 | unit_counter = 1; 168 | while (current_unit_offset < block->offset) { 169 | unit = reinterpret_cast(reinterpret_cast(block + 1) + current_unit_offset); 170 | std::cout << "\t\t" << "Unit " << unit_counter << ": " << unit->length + sizeof(SMemoryUnitHeader) << std::endl; 171 | current_unit_offset += sizeof(SMemoryUnitHeader) + unit->length; 172 | unit_counter++; 173 | } 174 | 175 | std::cout << "\t" << "===============================" << std::endl; 176 | 177 | block = block->next; 178 | block_counter++; 179 | } 180 | } 181 | 182 | void AppShift::Memory::MemoryPool::startScope() 183 | { 184 | // Create new scope, on top of previous if exists 185 | if (this->currentScope == nullptr) { 186 | this->currentScope = new (this) SMemoryScopeHeader; 187 | this->currentScope->prevScope = nullptr; 188 | } 189 | else { 190 | SMemoryScopeHeader* new_scope = new (this) SMemoryScopeHeader; 191 | new_scope->prevScope = this->currentScope; 192 | this->currentScope = new_scope; 193 | } 194 | 195 | // Simply load the current offset & block to return to when scope ends 196 | this->currentScope->scopeOffset = this->currentBlock->offset - sizeof(SMemoryScopeHeader) - sizeof(SMemoryUnitHeader); 197 | this->currentScope->firstScopeBlock = this->currentBlock; 198 | } 199 | 200 | void AppShift::Memory::MemoryPool::endScope() 201 | { 202 | // Free all blocks until the start of scope 203 | while (this->currentBlock != this->currentScope->firstScopeBlock) { 204 | this->currentBlock = this->currentBlock->prev; 205 | std::free(this->currentBlock->next); 206 | this->currentBlock->next = nullptr; 207 | } 208 | 209 | this->currentBlock->offset = this->currentScope->scopeOffset; 210 | } 211 | 212 | void* operator new(size_t size, AppShift::Memory::MemoryPool* mp) { 213 | return mp->allocate(size); 214 | } 215 | 216 | void* operator new[](size_t size, AppShift::Memory::MemoryPool* mp) { 217 | return mp->allocate(size); 218 | } 219 | -------------------------------------------------------------------------------- /MemoryPool.h: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | #pragma once 21 | #define MEMORYPOOL_DEFAULT_BLOCK_SIZE 1024 * 1024 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace AppShift::Memory { 29 | // Simple error collection for memory pool 30 | enum class EMemoryErrors { 31 | CANNOT_CREATE_MEMORY_POOL, 32 | CANNOT_CREATE_BLOCK, 33 | OUT_OF_POOL, 34 | EXCEEDS_MAX_SIZE, 35 | CANNOT_CREATE_BLOCK_CHAIN 36 | }; 37 | 38 | // Header for a single memory block 39 | struct SMemoryBlockHeader { 40 | // Block data 41 | size_t blockSize; 42 | size_t offset; 43 | 44 | // Movement to other blocks 45 | SMemoryBlockHeader* next; 46 | SMemoryBlockHeader* prev; 47 | 48 | // Garbage management data 49 | size_t numberOfAllocated; 50 | size_t numberOfDeleted; 51 | }; 52 | 53 | // Header of a memory unit in the pool holding important metadata 54 | struct SMemoryUnitHeader { 55 | size_t length; 56 | SMemoryBlockHeader* container; 57 | }; 58 | 59 | // Header for a scope in memory 60 | struct SMemoryScopeHeader { 61 | size_t scopeOffset; 62 | SMemoryBlockHeader* firstScopeBlock; 63 | SMemoryScopeHeader* prevScope; 64 | }; 65 | 66 | class MemoryPool { 67 | public: 68 | /** 69 | * Creates a memory pool structure and initializes it 70 | * 71 | * @param size_t block_size Defines the default size of a block in the pool, by default uses MEMORYPOOL_DEFAULT_BLOCK_SIZE 72 | */ 73 | MemoryPool(size_t block_size = MEMORYPOOL_DEFAULT_BLOCK_SIZE); 74 | // Destructor 75 | ~MemoryPool(); 76 | 77 | // Data about the memory pool blocks 78 | SMemoryBlockHeader* firstBlock; 79 | SMemoryBlockHeader* currentBlock; 80 | size_t defaultBlockSize; 81 | 82 | // Data about memory scopes 83 | SMemoryScopeHeader* currentScope; 84 | 85 | /** 86 | * Create a new standalone memory block unattached to any memory pool 87 | * 88 | * @param size_t block_size Defines the default size of a block in the pool, by default uses MEMORYPOOL_DEFAULT_BLOCK_SIZE 89 | * 90 | * @returns SMemoryBlockHeader* Pointer to the header of the memory block 91 | */ 92 | void createMemoryBlock(size_t block_size = MEMORYPOOL_DEFAULT_BLOCK_SIZE); 93 | 94 | /** 95 | * Allocates memory in a pool 96 | * 97 | * @param MemoryPool* mp Memory pool to allocate memory in 98 | * @param size_t size Size to allocate in memory pool 99 | * 100 | * @returns void* Pointer to the newly allocate space 101 | */ 102 | void* allocate(size_t size); 103 | 104 | // Templated allocation 105 | template 106 | T* allocate(size_t instances); 107 | 108 | /** 109 | * Re-allocates memory in a pool 110 | * 111 | * @param void* unit_pointer_start Pointer to the object to re-allocate 112 | * @param size_t new_size New size to allocate in memory pool 113 | * 114 | * @returns void* Pointer to the newly allocate space 115 | */ 116 | void* reallocate(void* unit_pointer_start, size_t new_size); 117 | 118 | // Templated re-allocation 119 | template 120 | T* reallocate(T* unit_pointer_start, size_t new_size); 121 | 122 | /** 123 | * Frees memory in a pool 124 | * 125 | * @param void* unit_pointer_start Pointer to the object to free 126 | */ 127 | void free(void* unit_pointer_start); 128 | 129 | /** 130 | * Dump memory pool meta data of blocks unit to stream. 131 | * Might be useful for debugging and analyzing memory usage 132 | * 133 | * @param MemoryPool* mp Memory pool to dump data from 134 | */ 135 | void dumpPoolData(); 136 | 137 | /** 138 | * Start a scope in the memory pool. 139 | * All the allocations between startScope and andScope will be freed. 140 | * It is a very efficient way to free multiple allocations 141 | * 142 | * @param MemoryPool* mp Memory pool to start the scope in 143 | */ 144 | void startScope(); 145 | 146 | /** 147 | * 148 | */ 149 | void endScope(); 150 | }; 151 | 152 | template 153 | inline T* MemoryPool::allocate(size_t instances) { 154 | return reinterpret_cast(this->allocate(instances * sizeof(T))); 155 | } 156 | 157 | template 158 | inline T* MemoryPool::reallocate(T* unit_pointer_start, size_t instances) { 159 | return reinterpret_cast(this->reallocate(reinterpret_cast(unit_pointer_start), instances * sizeof(T))); 160 | } 161 | } 162 | 163 | // Override new operators to create with memory pool 164 | extern void* operator new(size_t size, AppShift::Memory::MemoryPool* mp); 165 | extern void* operator new[](size_t size, AppShift::Memory::MemoryPool* mp); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemoryPool For C++ 2 | A very fast cross-platform memory pool mechanism for C++ built using a data-oriented approach. 3 | I hope this simple feature will help you increase your software's performance - and there are more projects and features to come under the AppShift library name, wait for it ;) 4 | 5 | # Table of Contents 6 | - [MemoryPool For C++](#memorypool-for-c) 7 | - [Table of Contents](#table-of-contents) 8 | - [Usage](#usage) 9 | - [Memory scoping](#memory-scoping) 10 | - [Macros](#macros) 11 | - [Methodology](#methodology) 12 | - [MemoryPool data (MemoryPool)](#memorypool-data-memorypool) 13 | - [Memory Block (SMemoryBlockHeader)](#memory-block-smemoryblockheader) 14 | - [Memory Unit (SMemoryUnitHeader)](#memory-unit-smemoryunitheader) 15 | - [Memory Scope (SMemoryScopeHeader)](#memory-scope-smemoryscopeheader) 16 | - [Benchmark](#benchmark) 17 | - [Windows & CLang](#windows--clang) 18 | - [Windows & MSVC](#windows--msvc) 19 | - [MacOS & CLang](#macos--clang) 20 | - [About](#about) 21 | - [Contributors - Thank You! :D](#contributors---thank-you-d) 22 | - [More to come in later versions](#more-to-come-in-later-versions) 23 | 24 | 25 | # Usage 26 | To use the memory pool features you just need to copy the [MemoryPool.cpp](MemoryPool.cpp) & [MemoryPool.h](MemoryPool.h) files to your project. The memory pool structure is `AppShift::Memory::MemoryPool`. ***The Memory Pool Is Not Thread Safe - In case of threads it is better to create a memory pool for each thread*** 27 | 28 | * _Create a memory pool_: `AppShift::Memory::MemoryPool * mp = new AppShift::Memory::MemoryPool(size);` Create a new memory pool structure and a first memory block. If you don't specify a size then by default it will be the `MEMORYPOOL_DEFAULT_BLOCK_SIZE` macro. 29 | * _Allocate space_: `Type* allocated = new (mp) Type[size];` or `Type* allocated = (Type*) mp->allocate(size * sizeof(Type));` or `Type* allocated = mp->allocate(size);` Where `Type` is the object\primitive type to create, `mp` is the memory pool object address, and `size` is a represention of the amount of types to allocate. 30 | * _Deallocate space_: `mp->free(allocated)` Remove an allocated space 31 | * _Reallocate space_: `Type* allocated = mp->reallocate(allocated, size);` or `Type* allocated = (Type*) mp->reallocate(allocated, size);` Rellocate a pre-allocated space, will copy the previous values to the new memory allocated. 32 | * _Dump data of a memory pool_: `mp->dumpPoolData()` This function prints outs the data about the blocks and units in the pool. 33 | 34 | ## Memory scoping 35 | Scoping is a fast way to deallocate many allocations at once. If for example you need to allocate more than once in a given part of the code, and then you deallocate all the allocations that happaned, then you can "scope" all these allocations together. it works the same way as a stack in a function scope. 36 | 37 | * _Start A Scope_: `mp->startScope()` where mp is the memory pool structure. This function creates a "checkpoint" of the offset and block in the memory pool. 38 | * _End A Scope_: `mp->endScope()` Will free all the allocations made after the scope started. 39 | * _Scope Inside A Scope_: You can nest scopes inside scopes by strating a new scope again, just the same way that the stack works with function scopes. Each scope is pointing to the previous one to create a chain that allows the memory pool manager to manage scope nesting. 40 | 41 | ## Macros 42 | There are some helpful macros available to indicate how you want the MemoryPool to manage your memory allocations. 43 | * `#define MEMORYPOOL_DEFAULT_BLOCK_SIZE 1024 * 1024`: The MemoryPool allocates memory into blocks, each block can have a maximum size avalable to use - when it exceeds this size, the MemoryPool allocates a new block - use this macro to define the maximum size to give to each block. By default the value is `1024 * 1024` which is 1MB. 44 | 45 | # Methodology 46 | The MemoryPool is a structure pointing to the start of a chain of blocks, which size of every block is by default `MEMORYPOOL_BLOCK_MAX_SIZE` macro (See [Macros](#macros)) or the size passed into the `AppShift::Memory::MemoryPool(size)` constructor. The MemoryPool is an object holding the necessary functions to work with the a memory pool. What's also good is that you can also access the MemoryPool structure data directly if needed (everything is public). 47 | 48 | ## MemoryPool data (MemoryPool) 49 | The memory pool structure holds meta-data about the memory space that is allocated and stored in the pool. 50 | * `SMemoryBlockHeader* firstBlock;` - Holds the first block in the chain of memory blocks. 51 | * `SMemoryBlockHeader* currentBlock;` - Holds the last block in the chain that is used first for allocating (allocations are happening in a stack manner, where each memory unit allocated is on top of the previous one, when a block reaches it's maximum size then a new block is allocated and added to the block chain of the pool). 52 | * `size_t defaultBlockSize;` - Default size to use when creating a new block, the size is defined by the `MEMORYPOOL_BLOCK_MAX_SIZE` macro or by passing the `size` as a parameter for the `AppShift::Memory::MemoryPoolManager::create(size)` function. 53 | * `SMemoryScopeHeader* currentScope;` - A pointer to the current scope in the memory pool. 54 | 55 | ## Memory Block (SMemoryBlockHeader) 56 | Each block contains a block header the size of 48 bytes containing the following information: 57 | * `size_t blockSize;` - Size of the block 58 | * `size_t offset;` - Offset in the block from which the memory is free (The block is filled in sequencial order) 59 | * `SMemoryBlockHeader* next;` - Pointer to the next block 60 | * `SMemoryBlockHeader* prev;` - Pointer to the previous block 61 | * `size_t numberOfAllocated` - Number of units currently allocated in this block. Helps smart garbage collection when block data has been freed. 62 | * `size_t numberOfDeleted` - Number of units that have been flaged as deleted. The system removes blocks by comparing the deleted with the allocated. 63 | 64 | When a block is fully filled the MemoryPool creates a new block and relates it to the previous block, and the previous to the current, them uses the new pool as the current block. 65 | 66 | ## Memory Unit (SMemoryUnitHeader) 67 | When allocating a space, MemoryPool creates a SMemoryUnitHeader and moves the blocks offset forward by the header size plus the amount of space requested. The header is 16 bytes long and contains the following data: 68 | * `size_t length;` - The length in bytes of the allocated space 69 | * `SMemoryBlockHeader* container` - Block which this unit belongs to 70 | 71 | ## Memory Scope (SMemoryScopeHeader) 72 | A scope has it's own structure - it has an offset and a pointer to the starting block of the scope, and also a pointer to the previous scope (parent). 73 | * `size_t scopeOffset;` - Saves the offset of the block when start scope is declared. 74 | * `SMemoryBlockHeader* firstScopeBlock;` - Saves the current block when a start scope is declared, helps to know until which block to free everything when the scope ends. 75 | * `SMemoryScopeHeader* prevScope;` - Pointer to the previous scope/NULL if no parent scope is present. 76 | 77 | # Benchmark 78 | ## Windows & CLang 79 |
80 | About 21-24 times faster than standard new/delete in each test. 81 | 82 | ## Windows & MSVC 83 |
84 | About 10-13 times faster than standard new/delete in each test. 85 | 86 | ## MacOS & CLang 87 |
88 | About 8-10 times faster than standard new/delete in each test. 89 | 90 | # About 91 | - ***Sapir Shemer*** is the proud business owner of [DevShift](https://devshift.biz) and an Open-Source enthusiast. Have been programming since the age of 7. Mathematics Student :) 92 | 93 | # Contributors - Thank You! :D 94 | A list of people that were kind enough to help: 95 | - [pwc357](https://github.com/pwc357) 96 | - [MyraBaba](https://github.com/MyraBaba) 97 | - [LastThought](https://www.reddit.com/user/LastThought/) 98 | - [azureskydiver](https://github.com/azureskydiver) 99 | 100 | # More to come in later versions 101 | In the next versions I'm planning to add some interesting features: 102 | - Ability to put thread safety on the memory pool to make a thread shared memory pool. 103 | - Ability to create an inter-process memory pool which can be shared between different processes. 104 | - `compressGarbage()`: Will compress deleted units that are next to eachother into one unit. 105 | 106 | ## Star History 107 | 108 | [![Star History Chart](https://api.star-history.com/svg?repos=DevShiftTeam/AppShift-MemoryPool&type=Date)](https://star-history.com/#DevShiftTeam/AppShift-MemoryPool&Date) 109 | -------------------------------------------------------------------------------- /benchmarks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | set(CMAKE_BUILD_TYPE Release) 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 8 | 9 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp" "String.cpp" "STDString.h" "STDString.cpp") -------------------------------------------------------------------------------- /benchmarks/STDString.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include "STDString.h" 22 | 23 | namespace AppShift { 24 | STDString::STDString(const char* str) 25 | { 26 | this->length = strlen(str); 27 | this->start = new char[this->length]; 28 | memcpy(this->start, str, this->length); 29 | } 30 | 31 | STDString::~STDString() { delete this->start; } 32 | 33 | char* STDString::data() const { return this->start; } 34 | 35 | size_t STDString::size() const { return this->length; } 36 | 37 | STDString& STDString::operator=(const char* str) 38 | { 39 | delete this->start; 40 | this->length = strlen(str); 41 | this->start = new char[this->length]; 42 | memcpy(this->start, str, this->length); 43 | return *this; 44 | } 45 | 46 | STDString& STDString::operator=(const STDString& str) 47 | { 48 | delete this->start; 49 | this->length = str.size(); 50 | this->start = new char[this->length]; 51 | memcpy(this->start, str.data(), this->length); 52 | return *this; 53 | } 54 | 55 | STDString& STDString::operator+=(const char* str) 56 | { 57 | int add_length = strlen(str); 58 | char* str_holder = new char[this->length + add_length]; 59 | memcpy(str_holder, this->start, this->length); 60 | memcpy(str_holder + this->length, str, add_length); 61 | delete this->start; 62 | this->start = str_holder; 63 | this->length += add_length; 64 | return *this; 65 | } 66 | 67 | STDString& STDString::operator+=(const STDString& str) 68 | { 69 | char* str_holder = new char[this->length + str.size()]; 70 | memcpy(str_holder, this->start, this->length); 71 | memcpy(str_holder + this->length, str.data(), str.size()); 72 | delete this->start; 73 | this->start = str_holder; 74 | this->length += str.size(); 75 | return *this; 76 | } 77 | 78 | std::ostream& operator<<(std::ostream& os, const STDString& str) 79 | { 80 | os << str.data(); 81 | os.flush(); 82 | return os; 83 | } 84 | } -------------------------------------------------------------------------------- /benchmarks/STDString.h: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "../MemoryPool.h" 24 | #include 25 | #include 26 | 27 | namespace AppShift { 28 | class STDString { 29 | public: 30 | STDString(const char* str = ""); 31 | ~STDString(); 32 | 33 | char* data() const; 34 | size_t size() const; 35 | 36 | STDString& operator=(const char* str); 37 | friend std::ostream& operator<<(std::ostream& os, const STDString& dt); 38 | STDString& operator=(const STDString& str); 39 | STDString& operator+=(const char* str); 40 | STDString& operator+=(const STDString& str); 41 | 42 | private: 43 | char* start; 44 | size_t length; 45 | }; 46 | } -------------------------------------------------------------------------------- /benchmarks/String.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include "String.h" 22 | 23 | namespace AppShift { 24 | String::String(Memory::MemoryPool* mp, const char* str) 25 | { 26 | this->mp = mp; 27 | this->length = strlen(str); 28 | this->start = new (mp) char[this->length + 1]; 29 | memcpy(this->start, str, this->length); 30 | this->start[this->length] = '\0'; 31 | } 32 | 33 | String::~String() { this->mp->free(this->start); } 34 | 35 | char* String::data() const { return this->start; } 36 | 37 | size_t String::size() const { return this->length; } 38 | 39 | String& String::operator=(const char* str) 40 | { 41 | this->mp->free(this->start); 42 | this->length = strlen(str); 43 | this->start = new (this->mp) char[this->length + 1]; 44 | memcpy(this->start, str, this->length); 45 | this->start[this->length] = '\0'; 46 | return *this; 47 | } 48 | 49 | String& String::operator=(const String& str) 50 | { 51 | this->mp->free(this->start); 52 | this->length = str.size(); 53 | this->start = new (this->mp) char[this->length + 1]; 54 | memcpy(this->start, str.data(), this->length); 55 | this->start[this->length] = '\0'; 56 | return *this; 57 | } 58 | 59 | String& String::operator+=(const char* str) 60 | { 61 | int add_length = strlen(str); 62 | this->start = (char*) this->mp->reallocate(this->start, this->length + add_length + 1); 63 | memcpy(this->start + this->length, str, add_length); 64 | this->length += add_length; 65 | this->start[this->length] = '\0'; 66 | return *this; 67 | } 68 | 69 | String& String::operator+=(const String& str) 70 | { 71 | this->start = (char*) this->mp->reallocate(this->start, this->length + str.size() + 1); 72 | memcpy(this->start + this->length, str.data(), str.size()); 73 | this->length += str.size(); 74 | this->start[this->length] = '\0'; 75 | return *this; 76 | } 77 | 78 | std::ostream& operator<<(std::ostream& os, const String& str) 79 | { 80 | os << str.data(); 81 | os.flush(); 82 | return os; 83 | } 84 | } -------------------------------------------------------------------------------- /benchmarks/String.h: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "../MemoryPool.h" 24 | #include 25 | #include 26 | 27 | namespace AppShift { 28 | class String { 29 | public: 30 | String(Memory::MemoryPool* mp, const char * str = ""); 31 | ~String(); 32 | 33 | char* data() const; 34 | size_t size() const; 35 | 36 | String& operator=(const char* str); 37 | friend std::ostream& operator<<(std::ostream& os, const String& dt); 38 | String& operator=(const String& str); 39 | String& operator+=(const char * str); 40 | String& operator+=(const String& str); 41 | 42 | private: 43 | char* start; 44 | size_t length; 45 | Memory::MemoryPool * mp; 46 | }; 47 | } -------------------------------------------------------------------------------- /benchmarks/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../MemoryPool.h" 23 | #include "String.h" 24 | #include "STDString.h" 25 | #include 26 | 27 | int main() { 28 | AppShift::Memory::MemoryPool * mp = new AppShift::Memory::MemoryPool(); 29 | 30 | clock_t t; 31 | long double benchavg = 0; 32 | long double benchavg_new = 0; 33 | 34 | for (long long int j = 0; j < 100; j++) { 35 | t = clock(); 36 | for (int i = 0; i < 1000000; i++) { 37 | AppShift::String strs(mp, "The Big World Is Great And Shit"); // Allocation 38 | strs += "Some new stuff"; // Re-allocation 39 | } // Dellocation 40 | t = clock() - t; 41 | benchavg += (t / (j + 1)) - (benchavg / (j + 1)); 42 | } 43 | 44 | std::cout << "AppShift Library: " << (benchavg * 1000) / CLOCKS_PER_SEC << std::endl; 45 | 46 | for (long long int j = 0; j < 100; j++) { 47 | t = clock(); 48 | for (int i = 0; i < 1000000; i++) { 49 | AppShift::STDString strs("The Big World Is Great And Shit"); // Allocation 50 | strs += "Some new stuff"; // Re-allocation 51 | } // Dellocation 52 | t = clock() - t; 53 | benchavg_new += (t / (j + 1)) - (benchavg_new / (j + 1)); 54 | } 55 | 56 | std::cout << "AppShift Library with regular new/delete: " << (benchavg_new * 1000) / CLOCKS_PER_SEC << std::endl; 57 | std::cout << "MemoryPool is " << benchavg_new / benchavg << " Times faster than new/delete" << std::endl; 58 | 59 | benchavg = 0; 60 | for (long long int j = 0; j < 100; j++) { 61 | t = clock(); 62 | for (int i = 0; i < 1000000; i++) { 63 | std::string strs("The Big World Is Great And Shit"); // Allocation 64 | strs += "Some new stuff"; // Rellocation 65 | } // Dellocation 66 | t = clock() - t; 67 | benchavg += (t / (j + 1)) - (benchavg / (j + 1)); 68 | } 69 | 70 | std::cout << "Standard Library: " << (benchavg * 1000) / CLOCKS_PER_SEC << std::endl; 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /images/MacOS_Benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevShiftTeam/AppShift-MemoryPool/8511bf0203103a5671da0d79e057a2e226cee18c/images/MacOS_Benchmark.png -------------------------------------------------------------------------------- /images/Windows_Benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevShiftTeam/AppShift-MemoryPool/8511bf0203103a5671da0d79e057a2e226cee18c/images/Windows_Benchmark.png -------------------------------------------------------------------------------- /images/Windows_Benchmark_CLang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevShiftTeam/AppShift-MemoryPool/8511bf0203103a5671da0d79e057a2e226cee18c/images/Windows_Benchmark_CLang.png -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/advanced_garbage_collection/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/advanced_garbage_collection/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../../MemoryPool.h" 23 | 24 | AppShift::Memory::MemoryPool testPool (256 * 1024); 25 | 26 | int main() { 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/overriding_new_delete/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/overriding_new_delete/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../../MemoryPool.h" 23 | 24 | AppShift::Memory::MemoryPool testPool (256 * 1024); 25 | 26 | int main() { 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/performance_mode/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/performance_mode/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../../MemoryPool.h" 23 | 24 | AppShift::Memory::MemoryPool testPool (256 * 1024); 25 | 26 | int main() { 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/simple_garbage_collection/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/simple_garbage_collection/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../../MemoryPool.h" 23 | 24 | AppShift::Memory::MemoryPool testPool (256 * 1024); 25 | 26 | int main() { 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/thread_safety/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(MemoryPool) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | # Release mode 7 | set(CMAKE_BUILD_TYPE Release) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 9 | 10 | # Debug mode 11 | # set(CMAKE_BUILD_TYPE Debug) 12 | 13 | add_executable(MemoryPool "main.cpp" "../MemoryPool.cpp") -------------------------------------------------------------------------------- /tests/thread_safety/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * AppShift Memory Pool v2.0.0 3 | * 4 | * Copyright 2020-present Sapir Shemer, DevShift (devshift.biz) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * @author Sapir Shemer 19 | */ 20 | 21 | #include 22 | #include "../../MemoryPool.h" 23 | 24 | AppShift::Memory::MemoryPool testPool (256 * 1024); 25 | 26 | int main() { 27 | return 0; 28 | } 29 | --------------------------------------------------------------------------------