Disable allocation zeroing in benchmarks on Android (#2214)

This is particularly problematic because large allocations partially used can get eagerly memset even if they hit the backing allocator, faulting in a ton of pages, so the behavior can diverge substantially from real in-app performance.
diff --git a/src/benchmark.cc b/src/benchmark.cc
index e866d29..2281785 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -30,6 +30,10 @@
 #include <unistd.h>
 #endif
 
+#ifdef __ANDROID_NDK__
+#include <malloc.h>
+#endif
+
 #ifdef BENCHMARK_OS_LINUX
 #include <sys/personality.h>
 #endif
@@ -902,6 +906,24 @@
 }
 
 void Initialize(int* argc, char** argv, void (*HelperPrintf)()) {
+#ifdef __ANDROID_NDK__
+  // We want standalone android benchmarks to match the performance properties
+  // of the production environment, so match that configuration here.
+
+  // Android 12 (API level 31) introduced zeroing of allocated memory in bionic
+  // as a hardening feature; however, this is not enabled for apps.
+  if (__builtin_available(android 31, *)) {
+    BM_CHECK_EQ(mallopt(M_BIONIC_ZERO_INIT, 0), 1);
+  }
+
+  // The default configuration of bionic is to return pages to the OS as soon
+  // as they are freed. But application processes are configured to run with a
+  // delay before returning memory to avoid excessive faulting on repeated
+  // allocation and deallocation, which is common in repeated benchmark runs.
+  if (__builtin_available(android 27, *)) {
+    BM_CHECK_EQ(mallopt(M_DECAY_TIME, 1), 1);
+  }
+#endif
   internal::HelperPrintf = HelperPrintf;
   internal::ParseCommandLineFlags(argc, argv);
   internal::LogLevel() = FLAGS_v;