From: drh <> Date: Wed, 26 Apr 2023 13:25:30 +0000 (+0000) Subject: Add scripts for JSON performance testing. X-Git-Tag: version-3.42.0~73^2~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=02efa7be9610963288319eb0f79a1a128d24bd5f;p=thirdparty%2Fsqlite.git Add scripts for JSON performance testing. FossilOrigin-Name: 3051d6a7c12cbf86634d8fab64f3f3bc9a1eb184260e56a82eb543cb634ba7ef --- diff --git a/manifest b/manifest index b5b8818efe..cc417d08a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sjson_valid()\sfunction\sonly\sreturns\strue\sfor\spure\sJSON.\s\sJSON5\s(or\nat\sleast\sthat\ssubset\sof\sJSON5\sthat\shas\sbeen\sso\sfar\simplemented)\sis\saccepted\nby\sall\sroutines,\sbut\sjson_valid()\sstill\sreturns\sfalse\sfor\sJSON5\sinputs.\nThe\snew\sjson_valid5(X)\sroutine\sreturns\strue\sor\sfalse\sif\sX\sis\sor\sis\snot\svalid\nJSON5.\s\sAll\sof\sthis\sis\sexperimental\sand\ssubject\sto\schange. -D 2023-04-25T21:24:20.117 +C Add\sscripts\sfor\sJSON\sperformance\stesting. +D 2023-04-26T13:25:30.498 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1249,6 +1249,10 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946 F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa +F test/json/README.md 9d117e0d6da9eee96de2fc8e32b603208b0e5b460ff99e5de3407bb713f0bb5c +F test/json/json-generator.tcl 229bd293f1865f787c160886cadd282631721925cca2947aaa54bbcd7f65cef7 +F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d +F test/json/json-speed-check.sh b1544c21e6f04e9c3ecc3caa858e0607703a4ed29d4d8b631a736d28e298ed9d x F test/json101.test 7241ab038c75ba780b009c6f37e4b660e5e63d1d74c110336a4779a2db8653f7 F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe @@ -2059,8 +2063,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4031b231c223db598b45dbd192b027a99a9b82a981d43c75f723a3fb06720b82 -R 4aa06ba3d655f30dc5fe96279fd3a8e6 +P 5d33ab77800765c8b3a13ffcc02ba8a348d71b2b425924560418b517d723494d +R 370adb66bc2173cabe35b75b43054560 U drh -Z 9b40834215aad90a070495da8b812bef +Z 49f1c31b7a1708965e204247b5ad4fd6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9efb7f40f..96d71859fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d33ab77800765c8b3a13ffcc02ba8a348d71b2b425924560418b517d723494d \ No newline at end of file +3051d6a7c12cbf86634d8fab64f3f3bc9a1eb184260e56a82eb543cb634ba7ef \ No newline at end of file diff --git a/test/json/README.md b/test/json/README.md new file mode 100644 index 0000000000..94f5516c06 --- /dev/null +++ b/test/json/README.md @@ -0,0 +1,26 @@ +The files in this subdirectory are used to help measure the performance +of the SQLite JSON parser. + +# 1.0 Prerequisites + + 1. Valgrind + + 2. Fossil + +# 2.0 Setup + + 1. Run: "`tclsh json-generator.tcl | sqlite3 json100mb.db`" to create + the 100 megabyte test database. Do this so that the "json100mb.db" + file lands in the same directory as the json-generator.tcl script. + + 2. Build the baseline sqlite3.c file. ("`make sqlite3.c`") + + 3. Run "`sh json-speed-check-1.sh trunk`". This creates the baseline + profile in "jout-trunk.txt". + +# 3.0 Testing + + 1. Build the sqlite3.c to be tested. + + 2. Run "`sh json-speed-check-1.sh x1`". The profile output will appear + in jout-x1.txt. Substitute any label you want in place of "x1". diff --git a/test/json/json-generator.tcl b/test/json/json-generator.tcl new file mode 100644 index 0000000000..e99d6bccb0 --- /dev/null +++ b/test/json/json-generator.tcl @@ -0,0 +1,401 @@ +#!/usr/bin/tclsh +# +# Generate SQL that will populate an SQLite database with about 100 megabytes +# of pseudo-random JSON text. +# +# tclsh json-generator.tcl | sqlite3 json110mb.db +# +# srand() is used to initialize the random seed so that the same JSON +# is generated for every run. +# +expr srand(12345678) +set wordlist { +ability able abroad access account act + action active actor add address adept + adroit advance advice affect age ageless + agency agent agile agree air airfare + airline airport alert almond alpha always + amend amount amplify analyst anchor angel + angelic angle ankle annual answer antique + anybody anyhow appeal apple apricot apt + area argon arm army arrival arsenic + art artful article arugula aside ask + aspect assist assume atom atone attempt + author autumn average avocado award awl + azure back bacon bag bagel bake + baker balance ball balloon bamboo banana + band banjo bank barium base basil + basin basis basket bass bat bath + battery beach beak bean bear bearcub + beauty beef beet beige being bell + belly belt bench bend benefit best + beta better beyond bicycle bid big + bike bill bird biscuit bismuth bisque + bit black blank blest blind bliss + block bloom blue board boat body + bokchoy bone bonus book bookish boot + border boron boss bossy bottle bottom + bow bowl bowtie box brain brainy + branch brave bravely bread break breath + breezy brick bridge brie brief briefly + bright broad broil bromine bronze brother + brow brown brush buddy budget buffalo + bug bugle bull bunch burger burly + burrito bus busy butter button buy + buyer byte cab cabbage cabinet cable + cadet cadmium caesium cake calcium caliper + call caller calm calmly camera camp + can canary cancel candle candy cap + capable caper capital captain car carbon + card care career careful carp carpet + carrot carry case cash cassava casual + cat catch catfish catsear catsup cause + cave celery cell century chain chair + chalk chance change channel chapter chard + charge charity chart check cheddar cheery + cheese chicken chicory chiffon child chin + chip chives choice chowder chum church + circle city claim clam class classic + classy clay clean cleaner clear clearly + clerk click client climate clock clorine + closet clothes cloud clown club clue + cluster coach coast coat cobbler cobolt + cod code coffee colby cold collar + college comb combine comet comfort command + comment common company complex concept concern + concert conduit consist contact contest context + control convert cook cookie copilot copper + copy coral cordial corn corner corny + correct cost count counter country county + couple courage course court cover cow + cowbird crab crack craft crash crazy + cream credit creek cress crevice crew + crimson croaker crop cross crowd cube + cuckoo cuisine culture cup current curve + cut cyan cycle dagger daily dance + dare darter data date day daylily + deal dear dearly debate debit decade + decimal deep deft deftly degree delay + deluxe deposit depth design desk detail + device dew diamond diet dig dill + dinner dip direct dirt dish disk + display diver divide divine doctor dodger + donut door dot double dough draft + drag dragon drama draw drawer drawing + dream drill drink drive driver drop + drum dry dryer drywall duck due + dump dusk dust duty dye eagle + ear earring earth ease east easy + eat economy edge editor eel effect + effort egg eight elbow elegant element + elf elk email emerald employ end + endive endless energy engine enjoy enter + entry equal equip error escape essay + eternal evening event exam example excuse + exit expert extent extreme eye face + fact factor factual fail failure fair + fajita fall family fan fang farm + farmer fat fault feature feed feel + feeling fench fennel festive few fiber + field fig figure file fill film + filter final finance finding finger finish + fire fish fishing fit fitting five + fix flier flight floor floral florine + flour flow flower fly flying focus + fold folding food foot force forest + forever forgive form formal format fortune + forum frame free freedom freely fresh + friend frog front fruit fuchsia fuel + fun funny future gain galaxy gallium + game gamma gap garage garden garlic + gas gate gather gauge gear gem + gene general gentle gently gherkin ghost + gift give glad glass gleeful glossy + glove glue goal goat goby gold + goldeye golf good gouda goulash gourd + grab grace grade gram grand grape + grapes grass gravy gray great green + grits grocery ground group grouper grout + growth guard guave guess guest guide + guitar gumbo guppy habit hacksaw haddock + hafnium hagfish hair half halibut hall + hammer hand handle handy hanger happy + hat havarti hay haybale head health + healthy hearing heart hearty heat heavy + heel height helium hello help helpful + herald herring hide high highly highway + hill hip hipster hire history hit + hoki hold hole holiday holly home + honest honey hook hope hopeful horizon + horn horse host hotel hour house + housing human humane humor hunt hurry + ice icecube icefish icy idea ideal + image impact impress inch income indigo + initial inkpen insect inside intense invite + iodine iridium iron island issue item + ivory jacket jargon javelin jello jelly + jewel job jocund join joint joke + jovial joy joyful joyous judge juice + jump junior jury just justice kale + keel keep kelp ketchup key keyhole + keyway khaki kick kid kidney kiloohm + kind kindly king kitchen kite kiwi + knee knife krill krypton kumquat lab + lace lack ladder lake lamp lamprey + land laser laugh law lawn lawyer + layer lead leader leading leaf leafy + league leather leave lecture leek leg + lemon length lentil lesson let letter + lettuce level library life lift light + lily lime limit line linen link + lip list listen lithium lively living + lizard load loan lobster local lock + log long longfin look lotus love + lovely loving low lucid luck luffa + lunch lung machine magenta magnet mail + main major make mall manager mango + manner many map march market maroon + martian master match math matter maximum + maybe meal meaning meat media medium + meet meeting melody melon member memory + mention menu mercury merry mess message + messy metal meter method micron middle + might mile milk mind mine minimum + minnow minor mint minute mirror miss + mission misty mix mixer mixture mobile + mode model moment monitor monk month + moon moray morning most motor mouse + mouth move mover movie much mud + mudfish muffin mullet munster muon muscle + music mustard nail name nation native + natural nature navy neat neatly nebula + neck needle neon nerve net network + neutron news nibble nice nickel night + niobium nobody noise noodle normal north + nose note nothing notice nova novel + number nurse nursery oar object offer + office officer oil okay okra old + olive one onion open opening opinion + option orange orbit orchid order oregano + other ounce outcome outside oven owner + oxygen oyster pace pack package page + pager paint pair pale pan pancake + papaya paper pardon parent park parking + parsley parsnip part partner party pass + passage past pasta path patient pattern + pause pay pea peace peach peacock + peahen peak peanut pear pearl pen + penalty pencil pension people pepper perch + perfect period permit person phase phone + photo phrase physics piano pick picture + pie piece pigeon pike pilot pin + pink pinkie pious pipe pitch pizza + place plan plane planet plant planter + plastic plate play player playful plenty + pliers plum pod poem poet poetry + point police policy pollock pony pool + pop popover poptart pork port portal + post pot potato pound powder power + present press price pride primary print + prior private prize problem process produce + product profile profit program project promise + prompt proof proper protein proton public + puff puffer pull pumpkin pup pupfish + pure purple purpose push put quality + quark quarter quiet quill quit quote + rabbit raccoon race radiant radio radish + radium radon rain rainbow raise ramp + ranch range rasp rate ratio ray + razor reach read reading real reality + reason recipe record recover red redeem + reed reef refuse region regret regular + relaxed release relief relish remote remove + rent repair repeat reply report request + reserve resist resolve resort rest result + return reveal review reward ribbon rice + rich ride ridge right ring rise + risk river rivet road roast rock + rocket role roll roof room rope + rose rough roughy round row royal + rub ruby rudder ruin rule run + runner rush rust sacred saddle safe + safety sail salad salami sale salmon + salt sample sand sander sandy sauce + save saving saw scale scampi scene + scheme school score screen script sea + search season seat second secret sector + seemly self sell senate senior sense + series serve set shake shape share + shark shell shift shine shiny ship + shock shoe shoot shop shovel show + side sign signal silk silly silver + simple sing singer single sink site + size skill skin sky slate sleep + sleepy slice slide slip smart smell + smelt smile smoke smooth snap snipe + snow snowy sock socket sodium soft + softly soil sole solid song sorrel + sort soul sound soup source south + space spare speech speed spell spend + sphere spice spider spirit spite split + spoon sport spot spray spread spring + squab square squash stable staff stage + stand staple star start state status + stay steak steel step stern stew + stick still stock stone stop store + storm story strain street stress strike + string stroke strong studio study stuff + style sugar suit sulfur summer sun + sunny sunset super superb surf survey + sweet swim swing switch symbol system + table tackle tail tale talk tan + tank tap tape target task taste + tau tea teach teal team tear + tell ten tender tennis tent term + test tetra text thanks theme theory + thing think thread throat thumb ticket + tidy tie tiger till time timely + tin tip title toast today toe + tomato tone tongue tool tooth top + topic total touch tough tour towel + tower town track trade train trash + travel tray treat tree trick trip + trout trowel truck trupet trust truth + try tube tuna tune turf turkey + turn turnip tutor tux tweet twist + two type union unique unit upbeat + upper use useful user usual valley + value van vase vast veil vein + velvet verse very vessel vest video + view violet visit visual vivid voice + volume vowel voyage waffle wait wake + walk wall warm warmth wasabi wash + watch water wave wax way wealth + wear web wedge week weekly weight + west whale what wheat wheel when + where while who whole why will + win wind window wing winner winter + wire wish witty wolf wonder wood + wool woolly word work worker world + worry worth worthy wrap wrench wrist + writer xenon yak yam yard yarrow + year yearly yellow yew yogurt young + youth zebra zephyr zinc zone zoo +} +set nwordlist [llength $wordlist] + +proc random_char {} { + return [string index \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + [expr {int(rand()*52)}]] +} +proc random_label {} { + set label [random_char] + while {rand()>0.8} { + append label [random_char] + } + if {rand()>0.9} {append label -} + append label [format %d [expr {int(rand()*100)}]] + return $label +} +proc random_numeric {} { + set n [expr {(rand()*2-1.0)*1e6}] + switch [expr {int(rand()*6)}] { + 0 {set format %.3f} + 1 {set format %.6E} + 2 {set format %.4e} + default {set format %g} + } + return [format $format $n] +} + + +proc random_json {limit indent} { + global nwordlist wordlist + set res {} + if {$indent==0 || ($limit>0 && rand()>0.5)} { + incr limit -1 + incr indent 2 + set n [expr {int(rand()*5)+1}] + if {$n==5} {incr n [expr {int(rand()*10)}]} + if {rand()>0.5} { + set res \173\n + for {set i 0} {$i<$n} {incr i} { + append res [string repeat { } $indent] + if {rand()>0.8} { + if {rand()>0.5} { + set sep ":\n [string repeat { } $indent]" + } else { + set sep " : " + } + } else { + set sep : + } + append res \"[random_label]\"$sep[random_json $limit $indent] + if {$i<$n-1} {append res ,} + append res \n + } + incr indent -2 + append res [string repeat { } $indent] + append res \175 + return $res + } else { + set res \[\n + for {set i 0} {$i<$n} {incr i} { + append res [string repeat { } $indent] + append res [random_json $limit $indent] + if {$i<$n-1} {append res ,} + append res \n + } + incr indent -2 + append res [string repeat { } $indent] + append res \] + return $res + } + } elseif {rand()>0.9} { + if {rand()>0.7} {return "true"} + if {rand()>0.5} {return "false"} + return "null" + } elseif {rand()>0.5} { + return [random_numeric] + } else { + set res \" + set n [expr {int(rand()*4)+1}] + if {$n>=4} {set n [expr {$n+int(rand()*6)}]} + for {set i 0} {$i<$n} {incr i} { + if {rand()<0.05} { + set w [random_numeric] + } else { + set k [expr {int(rand()*$nwordlist)}] + set w [lindex $wordlist $k] + } + if {rand()<0.07} { + set w \\\"$w\\\" + } + if {$i<$n-1} { + switch [expr {int(rand()*9)}] { + 0 {set sp {, }} + 1 {set sp "\\n "} + 2 {set sp "-"} + default {set sp { }} + } + append res $w$sp + } else { + append res $w + if {rand()<0.2} {append res .} + } + } + return $res\" + } +} + +puts "CREATE TABLE IF NOT EXISTS data1(x JSON);" +puts "BEGIN;" +set sz 0 +for {set i 0} {$sz<100000000} {incr i} { + set j [random_json 7 0] + incr sz [string length $j] + puts "INSERT INTO data1(x) VALUES('$j');" +} +puts "COMMIT;" +puts "SELECT sum(length(x)) FROM data1;" diff --git a/test/json/json-q1.txt b/test/json/json-q1.txt new file mode 100644 index 0000000000..0395f0c061 --- /dev/null +++ b/test/json/json-q1.txt @@ -0,0 +1,4 @@ +.mode qbox +.timer on +.param set $label 'q87' +SELECT rowid, x->>$label FROM data1 WHERE x->>$label IS NOT NULL; diff --git a/test/json/json-speed-check.sh b/test/json/json-speed-check.sh new file mode 100755 index 0000000000..01147c18be --- /dev/null +++ b/test/json/json-speed-check.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# +# This is a template for a script used for day-to-day size and +# performance monitoring of SQLite. Typical usage: +# +# sh speed-check.sh trunk # Baseline measurement of trunk +# sh speed-check.sh x1 # Measure some experimental change +# fossil xdiff --tk jout-trunk.txt jout-x1.txt # View chanages +# +# There are multiple output files, all with a base name given by +# the first argument: +# +# summary-$BASE.txt # Copy of standard output +# jout-$BASE.txt # cachegrind output +# explain-$BASE.txt # EXPLAIN listings (only with --explain) +# +if test "$1" = "" +then + echo "Usage: $0 OUTPUTFILE [OPTIONS]" + exit +fi +NAME=$1 +shift +#CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" +CC_OPTS="-DSQLITE_ENABLE_MEMSYS5" +CC=gcc +LEAN_OPTS="-DSQLITE_THREADSAFE=0" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_MEMSTATUS=0" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOBS" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_MAX_EXPR_DEPTH=0" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA" +BASELINE="trunk" +doExplain=0 +doCachegrind=1 +doVdbeProfile=0 +doWal=1 +doDiff=1 +while test "$1" != ""; do + case $1 in + --nodiff) + doDiff=0 + ;; + --lean) + CC_OPTS="$CC_OPTS $LEAN_OPTS" + ;; + --clang) + CC=clang + ;; + --gcc7) + CC=gcc-7 + ;; + -*) + CC_OPTS="$CC_OPTS $1" + ;; + *) + BASELINE=$1 + ;; + esac + shift +done +echo "NAME = $NAME" | tee summary-$NAME.txt +echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt +rm -f cachegrind.out.* jsonshell +$CC -g -Os -Wall -I. $CC_OPTS ./shell.c ./sqlite3.c -o jsonshell -ldl -lpthread +ls -l jsonshell | tee -a summary-$NAME.txt +home=/home/drh/sqlite/json-perf +valgrind --tool=cachegrind ./jsonshell $home/json100mb.db <$home/json-q1.txt \ + 2>&1 | tee -a summary-$NAME.txt +cg_anno.tcl cachegrind.out.* >jout-$NAME.txt +echo '*****************************************************' >>jout-$NAME.txt +sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>jout-$NAME.txt +if test "$NAME" != "$BASELINE"; then + fossil xdiff --tk -c 20 jout-$BASELINE.txt jout-$NAME.txt +fi