Skip to content

Commit 60f6ba1

Browse files
authored
Try some performance optimizations (#353)
* Try performance optimization * Show performance test result * Add GCC optimization level to podspec * Clean up C flags * Improve messages * Do not look up bundles unless necessary * Update tsconfig * Go back to RN 0.82 * Yarn lock
1 parent ffc3eeb commit 60f6ba1

File tree

12 files changed

+478
-248
lines changed

12 files changed

+478
-248
lines changed

android/build.gradle

Lines changed: 55 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,27 @@ if(useSQLCipher) {
8585
}
8686

8787
if(useCRSQLite) {
88-
println "[OP-SQLITE] using CR-SQLite 🤖"
88+
println "[OP-SQLITE] using CR-SQLite"
8989
}
9090

9191
if(performanceMode) {
92-
println "[OP-SQLITE] Performance mode enabled! 🚀"
92+
println "[OP-SQLITE] Performance mode enabled"
9393
}
9494

9595
if(enableFTS5) {
96-
println "[OP-SQLITE] FTS5 enabled! 🔎"
96+
println "[OP-SQLITE] FTS5 enabled"
9797
}
9898

9999
if(enableRtree) {
100-
println "[OP-SQLITE] RTree enabled! 🌲"
100+
println "[OP-SQLITE] RTree enabled"
101101
}
102102

103103
if(useSqliteVec) {
104-
println "[OP-SQLITE] Sqlite Vec enabled! ↗️"
104+
println "[OP-SQLITE] Sqlite-vec enabled"
105105
}
106106

107-
108107
if (!tokenizers.isEmpty()) {
109-
println "[OP-SQLITE] Tokenizers enabled! 🧾 Tokenizers: " + tokenizers
108+
println "[OP-SQLITE] Tokenizers enabled. Detected tokenizers: " + tokenizers
110109
}
111110

112111
android {
@@ -120,58 +119,58 @@ android {
120119

121120
externalNativeBuild {
122121
cmake {
123-
if(useSQLCipher) {
124-
cFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
125-
cppFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
126-
}
127-
if(useLibsql) {
128-
cFlags += "-DOP_SQLITE_USE_LIBSQL=1"
129-
cppFlags += "-DOP_SQLITE_USE_LIBSQL=1"
130-
}
131-
if(useCRSQLite) {
132-
cFlags += "-DOP_SQLITE_USE_CRSQLITE=1"
133-
cppFlags += "-DOP_SQLITE_USE_CRSQLITE=1"
134-
}
135-
if(performanceMode) {
136-
cFlags += ["-DSQLITE_DQS=0", "-DSQLITE_THREADSAFE=1", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1"]
137-
}
138-
if(enableFTS5) {
139-
cFlags += ["-DSQLITE_ENABLE_FTS5=1"]
140-
}
141-
if(enableRtree) {
142-
cFlags += ["-DSQLITE_ENABLE_RTREE=1"]
143-
}
144-
if(useSqliteVec) {
145-
cFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
146-
cppFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
147-
}
122+
if(useSQLCipher) {
123+
cFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
124+
cppFlags += "-DOP_SQLITE_USE_SQLCIPHER=1"
125+
}
126+
if(useLibsql) {
127+
cFlags += "-DOP_SQLITE_USE_LIBSQL=1"
128+
cppFlags += "-DOP_SQLITE_USE_LIBSQL=1"
129+
}
130+
if(useCRSQLite) {
131+
cFlags += "-DOP_SQLITE_USE_CRSQLITE=1"
132+
cppFlags += "-DOP_SQLITE_USE_CRSQLITE=1"
133+
}
134+
if(performanceMode) {
135+
cFlags += ["-DSQLITE_DQS=0", "-DSQLITE_DEFAULT_MEMSTATUS=0", "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1", "-DSQLITE_MAX_EXPR_DEPTH=0", "-DSQLITE_OMIT_DEPRECATED=1", "-DSQLITE_OMIT_PROGRESS_CALLBACK=1", "-DSQLITE_OMIT_SHARED_CACHE=1", "-DSQLITE_USE_ALLOCA=1", "-DSQLITE_THREADSAFE=1"]
136+
}
137+
if(enableFTS5) {
138+
cFlags += ["-DSQLITE_ENABLE_FTS5=1"]
139+
}
140+
if(enableRtree) {
141+
cFlags += ["-DSQLITE_ENABLE_RTREE=1"]
142+
}
143+
if(useSqliteVec) {
144+
cFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
145+
cppFlags += "-DOP_SQLITE_USE_SQLITE_VEC=1"
146+
}
148147

149-
// This are zeroes because they will be passed as C flags, so they become falsy
150-
def sourceFiles = 0
151-
// def tokenizerInitStrings = 0
152-
def tokenizersHeaderPath = 0
153-
if (!tokenizers.isEmpty()) {
154-
def sourceDir = isUserApp ? file("$rootDir/../../../c_sources") : file("$rootDir/../c_sources")
155-
def destDir = file("$buildscript.sourceFile.parentFile/c_sources")
156-
copy {
157-
from sourceDir
158-
into destDir
159-
include "**/*.cpp", "**/*.h"
148+
// This are zeroes because they will be passed as C flags, so they become falsy
149+
def sourceFiles = 0
150+
// def tokenizerInitStrings = 0
151+
def tokenizersHeaderPath = 0
152+
if (!tokenizers.isEmpty()) {
153+
def sourceDir = isUserApp ? file("$rootDir/../../../c_sources") : file("$rootDir/../c_sources")
154+
def destDir = file("$buildscript.sourceFile.parentFile/c_sources")
155+
copy {
156+
from sourceDir
157+
into destDir
158+
include "**/*.cpp", "**/*.h"
159+
}
160+
sourceFiles = fileTree(dir: destDir, include: ["**/*.cpp", "**/*.h"]).files.join(";")
161+
tokenizersHeaderPath = "../c_sources/tokenizers.h"
160162
}
161-
sourceFiles = fileTree(dir: destDir, include: ["**/*.cpp", "**/*.h"]).files.join(";")
162-
tokenizersHeaderPath = "../c_sources/tokenizers.h"
163-
}
164163

165-
cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
166-
arguments "-DANDROID_STL=c++_shared",
167-
"-DSQLITE_FLAGS='$sqliteFlags'",
168-
"-DUSE_SQLCIPHER=${useSQLCipher ? 1 : 0}",
169-
"-DUSE_CRSQLITE=${useCRSQLite ? 1 : 0}",
170-
"-DUSE_LIBSQL=${useLibsql ? 1 : 0}",
171-
"-DUSE_SQLITE_VEC=${useSqliteVec ? 1 : 0}",
172-
"-DUSER_DEFINED_SOURCE_FILES=${sourceFiles}",
173-
"-DUSER_DEFINED_TOKENIZERS_HEADER_PATH='${tokenizersHeaderPath}'",
174-
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
164+
cppFlags "-O3 -frtti -fexceptions -Wall -fstack-protector-all"
165+
arguments "-DANDROID_STL=c++_shared",
166+
"-DSQLITE_FLAGS='$sqliteFlags'",
167+
"-DUSE_SQLCIPHER=${useSQLCipher ? 1 : 0}",
168+
"-DUSE_CRSQLITE=${useCRSQLite ? 1 : 0}",
169+
"-DUSE_LIBSQL=${useLibsql ? 1 : 0}",
170+
"-DUSE_SQLITE_VEC=${useSqliteVec ? 1 : 0}",
171+
"-DUSER_DEFINED_SOURCE_FILES=${sourceFiles}",
172+
"-DUSER_DEFINED_TOKENIZERS_HEADER_PATH='${tokenizersHeaderPath}'",
173+
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
175174
}
176175
}
177176
}

example/android/app/src/main/kotlin/com/op/sqlite/example/MainApplication.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ class MainApplication : Application(), ReactApplication {
1717
getDefaultReactHost(
1818
context = applicationContext,
1919
packageList =
20-
PackageList(this).packages.apply {
21-
// Packages that cannot be autolinked yet can be added manually here, for example:
22-
// add(MyReactNativePackage())
23-
},
20+
PackageList(this).packages.apply { },
2421
)
2522
}
2623

example/ios/OPSQLiteExample.xcodeproj/project.pbxproj

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,10 @@
210210
inputFileListPaths = (
211211
"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
212212
);
213-
inputPaths = (
214-
);
215213
name = "[CP] Embed Pods Frameworks";
216214
outputFileListPaths = (
217215
"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
218216
);
219-
outputPaths = (
220-
);
221217
runOnlyForDeploymentPostprocessing = 0;
222218
shellPath = /bin/sh;
223219
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-frameworks.sh\"\n";
@@ -253,14 +249,10 @@
253249
inputFileListPaths = (
254250
"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-resources-${CONFIGURATION}-input-files.xcfilelist",
255251
);
256-
inputPaths = (
257-
);
258252
name = "[CP] Copy Pods Resources";
259253
outputFileListPaths = (
260254
"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-resources-${CONFIGURATION}-output-files.xcfilelist",
261255
);
262-
outputPaths = (
263-
);
264256
runOnlyForDeploymentPostprocessing = 0;
265257
shellPath = /bin/sh;
266258
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OPSQLiteExample/Pods-OPSQLiteExample-resources.sh\"\n";
@@ -315,6 +307,7 @@
315307
"$(inherited)",
316308
"@executable_path/Frameworks",
317309
);
310+
LLVM_LTO = NO;
318311
OTHER_LDFLAGS = (
319312
"$(inherited)",
320313
"-ObjC",
@@ -342,13 +335,15 @@
342335
CLANG_ENABLE_MODULES = YES;
343336
CURRENT_PROJECT_VERSION = 1;
344337
DEVELOPMENT_TEAM = 24CMR7378R;
338+
GCC_OPTIMIZATION_LEVEL = s;
345339
INFOPLIST_FILE = OPSQLiteExample/Info.plist;
346340
INFOPLIST_KEY_CFBundleDisplayName = "OP SQLite";
347341
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
348342
LD_RUNPATH_SEARCH_PATHS = (
349343
"$(inherited)",
350344
"@executable_path/Frameworks",
351345
);
346+
LLVM_LTO = NO;
352347
OTHER_LDFLAGS = (
353348
"$(inherited)",
354349
"-ObjC",
@@ -444,7 +439,10 @@
444439
);
445440
MTL_ENABLE_DEBUG_INFO = YES;
446441
ONLY_ACTIVE_ARCH = YES;
447-
OTHER_CFLAGS = "$(inherited) ";
442+
OTHER_CFLAGS = (
443+
"$(inherited)",
444+
" ",
445+
);
448446
OTHER_CPLUSPLUSFLAGS = (
449447
"$(OTHER_CFLAGS)",
450448
"-DFOLLY_NO_CONFIG",
@@ -532,7 +530,10 @@
532530
"\"$(inherited)\"",
533531
);
534532
MTL_ENABLE_DEBUG_INFO = NO;
535-
OTHER_CFLAGS = "$(inherited) ";
533+
OTHER_CFLAGS = (
534+
"$(inherited)",
535+
" ",
536+
);
536537
OTHER_CPLUSPLUSFLAGS = (
537538
"$(OTHER_CFLAGS)",
538539
"-DFOLLY_NO_CONFIG",

example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ PODS:
2525
- ReactCommon/turbomodule/core
2626
- ReactNativeDependencies
2727
- Yoga
28-
- OpServer (0.1.4):
28+
- OpServer (0.1.5):
2929
- hermes-engine
3030
- RCTRequired
3131
- RCTTypeSafety
@@ -2027,8 +2027,8 @@ EXTERNAL SOURCES:
20272027
SPEC CHECKSUMS:
20282028
FBLazyVector: 2e5b5553df729e080483373db6f045201ff4e6db
20292029
hermes-engine: 273e30e7fb618279934b0b95ffab60ecedb7acf5
2030-
op-sqlite: 7e1d781318b8f936bd7afe0773cf0d2e0b81780b
2031-
OpServer: 63fc523290a5c7c6f98dc7ba5e76cc720d798259
2030+
op-sqlite: d3b8002e984138ab1d6d88728adb0570db539901
2031+
OpServer: 9b3ebdeeb095950e760e3c39853cd06849421b35
20322032
RCTDeprecation: c6b36da89aa26090c8684d29c2868dcca2cd4554
20332033
RCTRequired: 1413a0844770d00fa1f1bb2da4680adfa8698065
20342034
RCTTypeSafety: 354b4bb344998550c45d054ef66913837948f958

example/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
"build:ios": "cd ios && xcodebuild -workspace OPSQLiteExample.xcworkspace -scheme debug -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"
1616
},
1717
"dependencies": {
18-
"@op-engineering/op-server": "^0.1.4",
19-
"@op-engineering/op-test": "^0.2.4",
18+
"@op-engineering/op-server": "^0.1.5",
19+
"@op-engineering/op-test": "^0.2.5",
2020
"chance": "^1.1.9",
2121
"clsx": "^2.0.0",
2222
"events": "^3.3.0",
@@ -33,7 +33,7 @@
3333
"@react-native-community/cli-platform-ios": "18.0.0",
3434
"@react-native/babel-preset": "0.82.1",
3535
"@react-native/metro-config": "0.82.1",
36-
"@react-native/typescript-config": "0.82.1",
36+
"@react-native/typescript-config": "0.81.5",
3737
"@types/chance": "^1.1.7",
3838
"@types/react": "^19.1.1",
3939
"react-native-builder-bob": "^0.40.13",
@@ -45,7 +45,7 @@
4545
"node": ">=18"
4646
},
4747
"op-sqlite": {
48-
"libsql": true,
48+
"libsql": false,
4949
"sqlcipher": false,
5050
"iosSqlite": false,
5151
"fts5": true,

example/src/App.tsx

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
import {useEffect, useState} from 'react';
2-
import {
3-
// setServerError,
4-
setServerResults,
5-
stopServer,
6-
} from './server';
2+
import {setServerResults, stopServer} from './server';
73
import {
84
displayResults,
95
runTests,
106
allTestsPassed,
117
} from '@op-engineering/op-test';
128
import './tests'; // import all tests to register them
13-
import {SafeAreaProvider} from 'react-native-safe-area-context';
9+
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
10+
import {performanceTest} from './performance_test';
11+
import {StyleSheet, Text, View} from 'react-native';
1412

1513
export default function App() {
1614
const [results, setResults] = useState<any>(null);
15+
const [perfResult, setPerfResult] = useState<number>(0);
1716
useEffect(() => {
18-
// registerTests();
19-
runTests()
20-
.then(newResults => {
21-
setServerResults(allTestsPassed(newResults));
22-
setResults(newResults);
23-
})
24-
.catch(_ => {
17+
const work = async () => {
18+
try {
19+
const results = await runTests();
20+
setServerResults(allTestsPassed(results));
21+
setResults(results);
22+
} catch (e) {
2523
setServerResults(false);
26-
});
24+
}
25+
26+
setTimeout(() => {
27+
try {
28+
global?.gc?.();
29+
let perfRes = performanceTest();
30+
setPerfResult(perfRes);
31+
} catch (e) {
32+
// intentionally left blank
33+
}
34+
}, 1000);
35+
};
36+
37+
work();
2738

2839
return () => {
2940
stopServer();
@@ -52,5 +63,32 @@ export default function App() {
5263
// }
5364
// };
5465

55-
return <SafeAreaProvider>{displayResults(results)}</SafeAreaProvider>;
66+
return (
67+
<SafeAreaProvider>
68+
<SafeAreaView style={styles.container}>
69+
<View>
70+
<Text style={styles.performanceText}>
71+
100_000 query time: {perfResult.toFixed(0)} ms
72+
</Text>
73+
</View>
74+
<View style={styles.results}>{displayResults(results)}</View>
75+
</SafeAreaView>
76+
</SafeAreaProvider>
77+
);
5678
}
79+
80+
const styles = StyleSheet.create({
81+
container: {
82+
flex: 1,
83+
backgroundColor: '#222',
84+
gap: 4,
85+
padding: 10,
86+
},
87+
results: {
88+
flex: 1,
89+
},
90+
performanceText: {
91+
color: 'white',
92+
fontSize: 16,
93+
},
94+
});

0 commit comments

Comments
 (0)