Skip to content

Instantly share code, notes, and snippets.

@miguelmartin75
Last active September 28, 2024 10:46
Show Gist options
  • Save miguelmartin75/c4ae6279099c20139481bf7b452456f5 to your computer and use it in GitHub Desktop.
Save miguelmartin75/c4ae6279099c20139481bf7b452456f5 to your computer and use it in GitHub Desktop.
json parse CLI example in nim, from https://x.com/lemire/status/1839881289312149549

SETUP:

Install nim

REPO_PATH=$HOME/repos
cd $REPO_PATH
git clone git@github.com:nim-lang/Nim.git
cd Nim
./build_all.sh

# add to your path - change to bashrc if you use bash
echo "export PATH='${REPO_PATH}/Nim/bin/:\$PATH'" >> ~/.zshrc

Now go to this repo location and run nimble install - nimble is used to install cligen. With cligen, you have CLI parsing based off function argument types - which is great for quick iteration speed. There are alternatives to this library.

Notably, for this example, we could have used commandLineParams() from std/cmdline

BENCHMARK:

The below will compile the nim program & run hyperfine on it for you:

nim benchmarkNim

Result: 3.5 ms ± 4.1 ms

For reference, here is python:

nim benchmarkPy

Result: 32.3 ms ± 4.2 ms

Example benchmarks were run on an M1 Max.

RUN IT YOURSELF:

The below compiles and runs the program on the input

nim c -d:release -r parse_json.nim --inputFile wealth.json

or:

nim compile
nim runExample

see config.nims for tasks

--outdir:"build"
--nimcache:"build/cache"
proc compile =
echo "compiling ..."
exec "nim c -d:release parse_json.nim"
task runExample, "run parse_json on the example json":
exec "./build/parse_json --inputFile ./wealth.json"
task compile, "compile and benchmark nim":
compile()
task benchmarkNim, "compile and benchmark nim":
compile()
exec "hyperfine --runs 1000 --warmup 100 './build/parse_json --inputFile ./wealth.json'"
task benchmarkPy, "compile and benchmark nim":
exec "hyperfine --runs 1000 'python3 parse_json.py ./wealth.json' --warmup 100"
import std/[json, strutils, strformat]
import cligen
proc main(inputFile: string) =
let
data = parseFile(inputFile)
wealthStr = data["user"]["wealth"].getStr
wealth = wealthStr.parseFloat
echo &"parse the wealth: {wealth:.2f}"
when isMainModule:
dispatch main
# Package
version = "0.1.0"
author = "Miguel Martin"
description = "A new awesome nimble package"
license = "MIT"
srcDir = "src"
# Dependencies
requires "nim >= 2.0.8"
requires "cligen"
import json
import sys
file_path = sys.argv[1]
with open(file_path, 'r') as file:
data = json.load(file)
wealth_str = data['user']['wealth']
wealth = float(wealth_str)
print(f"parsed the wealth {wealth:.2f}")
{
"user": {
"name": "John Doe",
"age": 30,
"email": "john@cia.gov.us",
"address": {
"street": "123 Main St",
"city": "Springfield",
"state": "IL",
"zip": "62701"
},
"phone": [
{
"type": "home",
"number": "217-555-5555"
},
{
"type": "work",
"number": "217-555-5556"
}
],
"children": [
{
"name": "Jane Doe",
"age": 5
},
{
"name": "Jesse Doe",
"age": 8
}
],
"wealth": "12321321321.128888"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment