A New JSON Library (2021)

Nice! Latest on my laptop:

                       fson :   1.0140  seconds
                      rojff :   0.3662  seconds
               json_fortran :   0.1368  seconds
2 Likes

Interesting…maybe I was misremembering. I thought the stream read made a difference.

@everythingfunctional What is the minimum version of GFortran needed to compile this library?
GFortran 9.3.0 (the default version on Ubuntu 20.04 LTS) fails with the following error messages:

 + gfortran -c ././src/rojff/json_integer_m.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/rojff -I build/gfortran_2A42023B310FA28D/rojff  -o build/gfortran_2A42023B310FA28D/rojff/src_rojff_json_integer_m.f90.o
././src/rojff/json_element_m.f90:36:24:

   36 |     recursive elemental function equals(lhs, rhs)
      |                        1
Error: ELEMENTAL attribute conflicts with RECURSIVE attribute at (1)
compilation terminated due to -fmax-errors=1.
././src/rojff/json_null_m.f90:50:37:

   50 |     subroutine write_to_expanded(self, indentation_level, sink)
      |                                     1
Warning: Unused dummy argument ‘self’ at (1) [-Wunused-dummy-argument]
././src/rojff/json_null_m.f90:43:38:

   43 |     subroutine write_to_compactly(self, sink)
      |                                      1
Warning: Unused dummy argument ‘self’ at (1) [-Wunused-dummy-argument]
././src/rojff/json_null_m.f90:30:33:

   30 |     elemental function equals(lhs, rhs)
      |                                 1
Warning: Unused dummy argument ‘lhs’ at (1) [-Wunused-dummy-argument]
././src/rojff/json_null_m.f90:20:44:

   20 |     function constructor() result(json_null)
      |                                            1
Warning: Return value ‘json_null’ of function ‘constructor’ declared at (1) not set [-Wreturn-type]
<ERROR> Compilation failed for object " src_rojff_json_element_m.f90.o "
<ERROR>stopping due to failed compilation
STOP 1

This is from using plain fpm build, btw. No additional options, no nothing.

Yeah, I ran into the same problem yesterday and had to make changes to my CI environment. 10 might work, but 11 definitely does.

I just tested with GFortran 10.3.0. Same error.

FYI: using strtod for the string to double conversion, and a few other minor tweaks, I’ve got JSON-Fortran parsing this canada.json file in 0.057 seconds with Gfortran 11.1. Amazing! Same order of magnitude as the python/C ones, although still not as fast, but a huge improvement from the read(fmt=*) version.

4 Likes

@jacobwilliams , would you care to try profiling of your JSON library now, say using Intel VTune Amplifier if gprof is suspect, to see what it might reveal to you on where the time is spent?

1 Like

I tried the same with my str2real function in your json-fortran:

original             : 0.117 s
str2real replacement : 0.051 s

I don’t know what your other tweaks did performance wise, but at least str2real seems to be competitive.

3 Likes

4 years later….

I’ve updated my benchmarks program with the latest version of everything (note that I have added some new json-fortran improvements for speed):

Fortran Library Runtime (sec)
json-fortran (c) 0.0447
json-fortran 0.0826
toml-f 0.1079
jsonf 0.2109
rojff 0.2829
jonquil 0.4208
fson 0.9652

Compared to Python:

Library Runtime (sec)
json 0.038878583
rapidjson 0.048005750
ujson 0.016822333

The “json_fortran (c)” one is just json-fortran with original string to real function replaced with the C function strtod (this is an option now you can use). So that makes a huge difference (recall this test file is mostly real numbers). Basically, we are just about the same speed now as the standard Python JSON module (although cheating a little bit by calling C).

9 Likes

This is pretty cool!

In case you are interested, I ran your benchmark as is first and got:

 json_fortran :   0.2122  seconds
json_fortran C:   0.1101  seconds

Then I included str2num from stdlib and just replaced in your lib

subroutine string_to_real(str,use_quiet_nan,rval,status_ok)
use stdlib_str2num, only: to_num
...
!read(str,fmt=*,iostat=ierr) rval
rval = to_num(str, rval)

getting:

 json_fortran :   0.1222  seconds
json_fortran C:   0.1134  seconds
8 Likes

If this is cheating, I want to see a Python implementation without “cheating”. :joy:

4 Likes

I added (2021) into the title, like the Hacker News style, to indicate that this new JSON library was new in 2021. Now it’s old. :slight_smile: But hopefully still good.

2 Likes

Still the one I like the most and have been using since 2020.

1 Like

Oh no, you guys found jsonf already :sweat_smile:

This side project is very immature, I just started hacking it on New Year’s Eve. I had a lexer/parser for the syntran programming language, so I thought it might be fun to adapt that into a json parser

I have barely thought about performance yet, so I’m surprised I’m not at the bottom of the benchmark list

3 Likes

Isn’t there an old saying about “everything old is new again” :grin:

1 Like