Skip to content

Integrate with mimalloc on Linux - #2708

Merged
jviotti merged 8 commits into
sourcemeta:mainfrom
Vansh-kap-98:feature/mimalloc-integration
Aug 14, 2026
Merged

Integrate with mimalloc on Linux#2708
jviotti merged 8 commits into
sourcemeta:mainfrom
Vansh-kap-98:feature/mimalloc-integration

Conversation

@Vansh-kap-98

@Vansh-kap-98 Vansh-kap-98 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR integrates mimalloc as an optional allocator path to significantly improve memory allocation performance during core benchmarking. The default allocator behavior remains unchanged for standard execution, ensuring stability while allowing us to specifically test and leverage mimalloc where intended.

1. Dependency and Vendoring Changes

  • Added mimalloc as a pinned vendored dependency in DEPENDENCIES.
  • Added a dedicated vendor mask file (mimalloc.mask) to strip non-essential upstream content during vendorpull. This keeps the vendored tree minimal for the repository's build use (cmake, include, src, etc.) and avoids carrying extra upstream documentation, tests, or tooling.
  • Hardened vendor-mask line endings to ensure future pulls are perfectly reproducible.

2. Build-System Integration

  • Added a new finder/build wrapper at FindMimalloc.cmake.
  • Configured the module to point to the vendored source directory via MIMALLOC_DIR.
  • Configured mimalloc with the intended options (static build path, tests/object output disabled, override enabled).
  • Utilized add_subdirectory so mimalloc is correctly built by its own upstream CMake logic.
  • Defined an internal alias target Mimalloc::Mimalloc for clean linking by project targets.

3. Results and findings

Aggregate of 10 runs for each, system vs mimalloc, major comparisons are as follows (><5%)

1. Regex Operations

Benchmark Performance Change
Regex_Lower_S_Or_Upper_S_Asterisk +11.4% Improvement
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar +10.0% Improvement
Regex_Period_Asterisk +9.6% Improvement
Regex_Group_Period_Asterisk_Group +11.0% Improvement
Regex_Period_Plus +11.3% Improvement
Regex_Period +11.4% Improvement
Regex_Caret_Period_Plus_Dollar +11.2% Improvement
Regex_Caret_Group_Period_Plus_Group_Dollar +10.2% Improvement
Regex_Caret_Period_Asterisk_Dollar +49.1% Improvement
Regex_Caret_Group_Period_Asterisk_Group_Dollar +59.7% Improvement
Regex_Caret_X_Hyphen +64.7% Improvement
Regex_Period_Md_Dollar +53.6% Improvement
Regex_Caret_Slash_Period_Asterisk +67.4% Improvement
Regex_Caret_Period_Range_Dollar +56.6% Improvement
Regex_Nested_Backtrack +54.8% Improvement

2. JSON & JSON-LD Operations

Benchmark Performance Change
JSON_Array_Of_Objects_Unique +44.6% Improvement
JSON_Parse_1 +49.5% Improvement
JSON_Parse_Real +56.2% Improvement
JSON_Parse_Decimal +53.6% Improvement
JSON_Parse_Schema_ISO_Language +53.1% Improvement
JSON_Parse_Integer +49.9% Improvement
JSON_Parse_String_NonSSO_Plain +52.7% Improvement
JSON_Parse_String_SSO_Plain +46.7% Improvement
JSON_Parse_String_Escape_Heavy +48.7% Improvement
JSON_Parse_Object_Short_Keys +48.3% Improvement
JSON_Parse_Object_Scalar_Properties +47.7% Improvement
JSON_Parse_Object_Array_Properties +44.6% Improvement
JSON_Parse_Object_Object_Properties +46.2% Improvement
JSON_Parse_Nested_Containers +50.7% Improvement
JSON_From_String_Copy +53.0% Improvement
JSON_From_String_Temporary +41.7% Improvement
JSON_Number_To_Double +6.2% Improvement
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 +5.7% Improvement
JSON_String_Fast_Hash/10 +8.5% Improvement
JSON_String_Fast_Hash/100 +6.9% Improvement
JSON_String_Key_Hash/10 25.0% Regression
JSONL_Parse_Large +41.8% Improvement
JSONLD_Catalog_Annotation_List_Populate +7.9% Improvement
JSONLD_Catalog_Materialize +8.1% Improvement

3. Pointer & JSONPath Operations

Benchmark Performance Change
Pointer_Object_Traverse +48.5% Improvement
Pointer_Object_Try_Traverse +55.1% Improvement
Pointer_Push_Back_Pointer_To_Weak_Pointer +45.0% Improvement
Pointer_Walker_Schema_ISO_Language +48.7% Improvement
Pointer_Maybe_Tracked_Deeply_Nested/0 +48.5% Improvement
Pointer_Maybe_Tracked_Deeply_Nested/1 +50.0% Improvement
Pointer_Position_Tracker_Get_Deeply_Nested +51.5% Improvement
JSONPath_Descendant_Filter_Nested +49.8% Improvement

4. URI Template Router Operations

Benchmark Performance Change
URITemplateRouter_Create +55.0% Improvement
URITemplateRouter_Match +62.5% Improvement
URITemplateRouter_Match_BasePath +51.0% Improvement
URITemplateRouterView_Restore +69.3% Improvement
URITemplateRouterView_Match +53.4% Improvement
URITemplateRouterView_Match_BasePath +52.7% Improvement
URITemplateRouterView_Arguments +58.4% Improvement

Review in cubic

Signed-off-by: Vansh <officialbusiness9818@gmail.com>
@Vansh-kap-98
Vansh-kap-98 force-pushed the feature/mimalloc-integration branch from 98b80e7 to 66cfe1d Compare August 6, 2026 07:47

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread benchmark/CMakeLists.txt Outdated
Comment thread benchmark/CMakeLists.txt Outdated
Comment thread benchmark/CMakeLists.txt
Comment thread cmake/FindMimalloc.cmake Outdated
Comment thread cmake/FindMimalloc.cmake Outdated
Comment thread CMakeLists.txt Outdated
@Vansh-kap-98
Vansh-kap-98 marked this pull request as draft August 6, 2026 10:04
… benchmark CMakeLists

Signed-off-by: Vansh <officialbusiness9818@gmail.com>
@Vansh-kap-98
Vansh-kap-98 marked this pull request as ready for review August 6, 2026 11:21

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 58 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="cmake/FindMimalloc.cmake">

<violation number="1" location="cmake/FindMimalloc.cmake:16">
P2: When a static mimalloc with MI_OVERRIDE is linked as an ordinary archive (not whole-archive), the linker may only pull in the objects that resolve currently-undefined symbols, so the malloc/free override can silently fail on some platforms or link orders. Consider propagating whole-archive linking (e.g. target_link_options with $<LINK_LIBRARY:WHOLE_ARCHIVE,mimalloc-static>, or linking the benchmark executable with --whole-archive) so the override that the benchmark gains depend on is guaranteed and reproducible.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread cmake/FindMimalloc.cmake Outdated
if(TARGET mimalloc-static)
set_target_properties(mimalloc-static
PROPERTIES COMPILE_WARNING_AS_ERROR OFF)
add_library(Mimalloc::Mimalloc ALIAS mimalloc-static)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a static mimalloc with MI_OVERRIDE is linked as an ordinary archive (not whole-archive), the linker may only pull in the objects that resolve currently-undefined symbols, so the malloc/free override can silently fail on some platforms or link orders. Consider propagating whole-archive linking (e.g. target_link_options with $<LINK_LIBRARY:WHOLE_ARCHIVE,mimalloc-static>, or linking the benchmark executable with --whole-archive) so the override that the benchmark gains depend on is guaranteed and reproducible.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At cmake/FindMimalloc.cmake, line 16:

<comment>When a static mimalloc with MI_OVERRIDE is linked as an ordinary archive (not whole-archive), the linker may only pull in the objects that resolve currently-undefined symbols, so the malloc/free override can silently fail on some platforms or link orders. Consider propagating whole-archive linking (e.g. target_link_options with $<LINK_LIBRARY:WHOLE_ARCHIVE,mimalloc-static>, or linking the benchmark executable with --whole-archive) so the override that the benchmark gains depend on is guaranteed and reproducible.</comment>

<file context>
@@ -0,0 +1,19 @@
+  if(TARGET mimalloc-static)
+    set_target_properties(mimalloc-static
+      PROPERTIES COMPILE_WARNING_AS_ERROR OFF)
+    add_library(Mimalloc::Mimalloc ALIAS mimalloc-static)
+    set(Mimalloc_FOUND ON)
+  endif()
</file context>

Comment thread CMakeLists.txt
Comment thread .gitignore Outdated
.cache
out/
CMakeSettings.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment thread CMakeLists.txt Outdated
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

# Options
#Options

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#Options
# Options

Comment thread CMakeLists.txt Outdated
endif()

# Enable the sanitizers before defining any target
#Enable the sanitizers before defining any target

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like in general most comments lost the initial space for some reason?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes i apologise for the missing spaces, while i was manually reviewing changes i instinctually removed the space out of habit. Im gonna review once again and revert these in the next commit.

Comment thread CMakeLists.txt Outdated
include(Sourcemeta)

# Don't force downstream consumers on this
sourcemeta_option_enum(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If minalloc is indeed consistently faster, then no need to have it as an option. Let's just compile it unconditionally?

Comment thread cmake/FindMimalloc.cmake Outdated
"${MIMALLOC_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/mimalloc" EXCLUDE_FROM_ALL)

if(TARGET mimalloc-static)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen on shared builds?

@jviotti

jviotti commented Aug 6, 2026

Copy link
Copy Markdown
Member

Very interesting! Given the speed bumps, left some comments about integrating it unconditionally. Probably no need to support multiple allocators. If this one is good, then let's just use it everywhere?

@Vansh-kap-98

Copy link
Copy Markdown
Contributor Author

Right now If we link it unconditionally across the whole project, every single DLL will embed its own independent static copy of mimalloc, which causes crashes.

it would work perfectly on unix but to make mimalloc globally override the system allocator on Windows, we will have to use special linking flags, force dynamic overrides, and carefully manage DLLs, so basically there is an extra risk factor

i suggest keeping mimalloc as optional as of right now, while if you want me to, i can work on making it unconditional and submit it as a separate PR in the future.

@jviotti

jviotti commented Aug 8, 2026

Copy link
Copy Markdown
Member

@Vansh-kap-98 What about we make it unconditionally ONLY for Linux to start with, as a first step? So on Linux, it's unconditional. The rest uses the default allocator.

The reason I'm pushing for not having the additional option is that it's a whole other alternate build configuration to maintain, with more additions to the CI matrix, etc. I much rather have a "blessed" configuration all projects operate on.

I tried it on my Mac and its not so easy there (there are caveats just like on Windows), so we can start Linux only, and try future PRs to make it work in the rest?

@Vansh-kap-98

Copy link
Copy Markdown
Contributor Author

@jviotti understood, ill remove the "optional" part and integrate it unconditionally for linux for this specific PR

@jviotti

jviotti commented Aug 9, 2026

Copy link
Copy Markdown
Member

Awesome, thanks! Let me know once the changes are made for me to take a look. Excited to land this!

Signed-off-by: Vansh <officialbusiness9818@gmail.com>
@cla-assistant

cla-assistant Bot commented Aug 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 9 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread cmake/common/targets/library.cmake Outdated
Comment thread .gitattributes Outdated
@Vansh-kap-98

Copy link
Copy Markdown
Contributor Author

still making some changes and reviews, just wanted to see the tests and cubic responses as im using docker and wsl to run the tests, ill tag you once i complete the task and verify all files

@jviotti

jviotti commented Aug 12, 2026

Copy link
Copy Markdown
Member

Awesome! And Yeah, feel free to iterate with CI here as much as you need to :)

Signed-off-by: Vansh <officialbusiness9818@gmail.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread cmake/common/targets/library.cmake Outdated
…omplete vendored install-skip coverage

Signed-off-by: Vansh <officialbusiness9818@gmail.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="patches/mimalloc/0001-Skip-vendored-install-rules-when-embedded.patch">

<violation number="1" location="patches/mimalloc/0001-Skip-vendored-install-rules-when-embedded.patch:91">
P2: The final hunk of this patch declares `@@ -819,8 +831,10 @@`, but its content is only 5 old lines and 7 new lines, so strict `git apply` rejects the entire patch as corrupt (`error: corrupt patch` at EOF). The count should be `-819,5 +831,7`. If the vendorpull flow uses `git apply`, pulling mimalloc breaks; if it uses lenient GNU `patch`, it is silently tolerated. Fix the hunk header counts to make the patch a well-formed unified diff regardless of the apply tool.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mimalloc.pc"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
+if(NOT MI_SKIP_INSTALL)
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mimalloc.pc"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The final hunk of this patch declares @@ -819,8 +831,10 @@, but its content is only 5 old lines and 7 new lines, so strict git apply rejects the entire patch as corrupt (error: corrupt patch at EOF). The count should be -819,5 +831,7. If the vendorpull flow uses git apply, pulling mimalloc breaks; if it uses lenient GNU patch, it is silently tolerated. Fix the hunk header counts to make the patch a well-formed unified diff regardless of the apply tool.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At patches/mimalloc/0001-Skip-vendored-install-rules-when-embedded.patch, line 91:

<comment>The final hunk of this patch declares `@@ -819,8 +831,10 @@`, but its content is only 5 old lines and 7 new lines, so strict `git apply` rejects the entire patch as corrupt (`error: corrupt patch` at EOF). The count should be `-819,5 +831,7`. If the vendorpull flow uses `git apply`, pulling mimalloc breaks; if it uses lenient GNU `patch`, it is silently tolerated. Fix the hunk header counts to make the patch a well-formed unified diff regardless of the apply tool.</comment>

<file context>
@@ -46,3 +66,28 @@ index 3189dec42..565852ecd 100644
+-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mimalloc.pc"
+-        DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
++if(NOT MI_SKIP_INSTALL)
++  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mimalloc.pc"
++          DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
++endif()
</file context>

Signed-off-by: Vansh <officialbusiness9818@gmail.com>
@Vansh-kap-98

Vansh-kap-98 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Hi @jviotti ,this should be ready for review now. CI is green across the full matrix including the sanitizer job. Let me know if you'd like anything adjusted.

edit: i forgot to mention
->mimalloc's allocator override and AddressSanitizer/UBSan both intercept malloc/operator new — running them together was an incompatibility and was actually causing a segfault in CI. mimalloc is now automatically disabled whenever a sanitizer is active, via a single centralized SOURCEMETA_CORE_MIMALLOC_ENABLED variable referenced consistently across CMakeLists.txt, library.cmake, and config.cmake.in, so the three can't drift out of sync.
->Full suite passes identically on Windows and Linux except for 4 pre-existing failures, independently confirmed unrelated to this change by reproducing each one with mimalloc disabled: core.io,core.aws_sigv4_suite, core.find_package_configure, core.find_package_build. None of these regress with mimalloc on vs. off, same 4 failures either way.

Comment thread .gitattributes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes really needed? Seem unrelated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes they are quite unrelated but i thought i should atleast point them out instead of just ignoring them, better safe than sorry

Comment thread .gitignore Outdated
Brewfile.lock.json
.DS_Store
.cache
out/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
out/
/out/

To prevent any directory called out in the future anywhere else nested in this project being silently ignored

Comment thread CMakeLists.txt Outdated
if(SOURCEMETA_OS_LINUX
AND NOT SOURCEMETA_CORE_ADDRESS_SANITIZER
AND NOT SOURCEMETA_CORE_UNDEFINED_SANITIZER)
set(SOURCEMETA_CORE_MIMALLOC_ENABLED ON)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move this to the Find script

@jviotti

jviotti commented Aug 14, 2026

Copy link
Copy Markdown
Member

Looks good. Mostly just very minor comments. Let me just push a commit here myself so we can merge this in a bit

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can get rid of this by setting up the dependency ourselves in the find script like for the others. But something to do in a subsequent PR to make sure performance is not sacrificed

Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
@jviotti jviotti changed the title mimalloc integration Integrate with mimalloc on Linux Aug 14, 2026
@jviotti
jviotti merged commit 64502dd into sourcemeta:main Aug 14, 2026
13 checks passed
@jviotti

jviotti commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks a lot! Some of the things I'll to explore soon:

  • Whether it can be made to build and run fine on both Windows and macOS
  • Try to have our own custom CMake setup over it to potentially remove the patch, etc
  • Study the allocator code to try to understand why it is faster. Writing our own allocator for this project is something I had on the radar for a while. I wonder how hard it would be after understanding why this one is faster

@Vansh-kap-98

Copy link
Copy Markdown
Contributor Author

@jviotti thanks a lot for allowing me to work on it, and im looking forward to working on this even more, i appreciate all the time and effort you put in reviewing my commits and providing insights. Ive noted everything and will make sure to work on them in the very near future and keep you updated.

@jviotti

jviotti commented Aug 14, 2026

Copy link
Copy Markdown
Member

@Vansh-kap-98 Any time! Excellent work and research behind this. This kind of stuff is super appreciated and massively impactful. If you like the performance research aspect of it, I would love your eyes on how do you think we could make the https://github.com/sourcemeta/blaze evaluator faster?

i.e. this part: https://github.com/sourcemeta/blaze/tree/main/src/evaluator

We have plenty of benchmark cases for the evaluator (though other stuff too).

@Vansh-kap-98

Copy link
Copy Markdown
Contributor Author

@jviotti okie, ill make sure to take a look and keep you updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants