Fork me on GitHub
#parinfer
<
2016-02-03
>
chrisoakman00:02:12

I did wrap the test suite in clojure.test today

chrisoakman00:02:26

and added some of the tests that occur in parinfer.js

cfleming00:02:28

Cool, I’ll make it so that lein test works, and then we can remove the main

chrisoakman00:02:52

I was going to add a really rudimentary speed tests

chrisoakman00:02:09

the same speed test as parinfer.py; just to see how it compares there

chrisoakman00:02:16

basically parsing cljs.core

chrisoakman00:02:28

but I fell asleep in my hammock 😉

cfleming00:02:26

Of course, I was doing this against my fork, and now I have to find the magic incantation to make git use the original repo

chrisoakman00:02:54

git remote set-url ?

cfleming00:02:05

Here’s hoping

cfleming00:02:52

@chrisoakman: Ok, this seems to work. I haven’t done anything to the code, but I’ve gradleised the main project (now under parinfer/ in the repo) and the tests now run using lein test and I’ve removed the main function.

cfleming00:02:58

I’ll push this now, one sec.

cfleming00:02:03

@chrisoakman: Done, take a look.

cfleming00:02:15

I haven’t updated the README, actually, I’ll do that shortly.

cfleming00:02:06

Under /paredit, do ./gradlew install, then under /paredit-test do lein test

chrisoakman00:02:43

ok - I'll test that out

chrisoakman00:02:49

doing the speed thing right now

cfleming00:02:18

I’m going to check the actual code after some lunch.

chrisoakman00:02:20

I'm seeing around ~600ms for indent and paren mode on cljs.core

chrisoakman00:02:31

if these timestamps are to be trusted

chrisoakman00:02:41

which is slower than Python and JS

chrisoakman00:02:49

which is a bummer, if that's true

chrisoakman00:02:23

there is something about how the JVM "warms up" though? and could effect the time if it had been running for a long time

cfleming00:02:05

@chrisoakman: How are you testing that?

chrisoakman00:02:05

so very rudimentary

cfleming00:02:52

Yeah, that won’t do it at all.

cfleming00:02:03

You really need to use criterium.

chrisoakman00:02:36

this is crazy...

chrisoakman00:02:40

you know my SENTINEL_NULL hack?

chrisoakman00:02:08

out of curiosity I made that same change to the JS version

chrisoakman00:02:20

seeing noticeable performance improvement because of it

chrisoakman00:02:29

gotta make sure this isn't a fluke...

cfleming00:02:39

I’m replacing that with actual nulls at the moment

cfleming00:02:46

In the JVM version.

chrisoakman01:02:37

we should probably get a performance testing harness up

cfleming01:02:00

@chrisoakman: I see what you mean about the null checking being difficult. It’s because the result fields are vars, so you don’t get a lot of the nice smart casting, because multiple threads might be modifying it concurrently.

chrisoakman01:02:09

man - this is nice simple_smile

chrisoakman01:02:12

you know about the JVM

chrisoakman01:02:21

and I'm very familiar with parinfer implementation algorithm

chrisoakman01:02:19

one big question I had was: is it faster to use Java Objects or a HashMap?

chrisoakman01:02:10

just tried the SENTINEL_NULL hack in Python: no speed improvement

chrisoakman01:02:49

if anything it might be a touch slower

chrisoakman01:02:55

this must be a JS engine optimization thing

chrisoakman01:02:56

under the hood

chrisoakman01:02:07

tell me I am not crazy:

chrisoakman01:02:26

but that is a noticeable perf improvement

cfleming02:02:11

That’s bizarre

chrisoakman02:02:22

just added a table of the result averages

chrisoakman02:02:30

it's almost hard to believe how much the difference is on the long file

chrisoakman03:02:07

@cfleming: we gotta set up a performance harness for the JVM version

chrisoakman03:02:27

actually - maybe more important to get it in Cursive first?

cfleming03:02:29

@chrisoakman: Ok, I’ll do that next.

cfleming03:02:41

No, I think we should perf test it.

cfleming03:02:47

I have some more changes to check in.

chrisoakman03:02:02

I can't even believe that JS difference; I'm double-checking my spreadsheet now

cfleming03:02:19

Yeah, that’s bizarre alright, but who knows what the JIT does with it?

chrisoakman03:02:22

I guess v8 optimizations are not to be under-estimated

cfleming03:02:28

Absolutely not.

cfleming03:02:53

I’m planning to create a ParenTrail object to store in result. I believe that can contain all non-nullable vars, and then MutableResult can just have a nullable ParenTrail ref.

cfleming03:02:17

That will avoid a bunch of null checks and casts I had to do to make Kotlin happy.

cfleming03:02:42

I have to go shortly, but the next thing I’ll do is set up a test harness for the perf testing.

chrisoakman03:02:44

you see I decided to just "add" the parenTrail object to the result?

cfleming03:02:10

Actually, I haven’t compared that closely to the JS yet, I will do.

chrisoakman03:02:23

in the JS and python version "parenTrail" is an object / dict

cfleming03:02:26

I have some changes I’m about to push, all tests still pass.

chrisoakman03:02:46

basically I didn't want to create another object definition, so I rolled it into the MutableResult object

chrisoakman03:02:03

but it would be closer in spirit to the JS version if there were a parenTrail object

cfleming03:02:09

Oh, that’s basically what I’m planning to do here - it’ll work better since then there’s just one check - do we have a paren trail or not, and not a bunch of null checks for each of the individual vars.

chrisoakman03:02:44

are objects faster than hashmaps?

chrisoakman03:02:56

that was my other big question

chrisoakman03:02:27

MutableResult could just be a HashMap

cfleming03:02:08

Yes, probably.

cfleming03:02:20

Again, have to test it, but almost certainly yes.

cfleming03:02:24

Just pushed my changes.

cfleming03:02:42

You’ll see a bunch of as Int casts, they can go with the ParenTrail change I think.

cfleming03:02:54

Ok, gotta go, talk to you later.

chrisoakman03:02:58

let's make sure we keep the README up-to-date

chrisoakman03:02:10

I'll add the new gradle instructions

cfleming08:02:57

Great, thanks.

cfleming23:02:20

@chrisoakman: Here are the perf results using Criterium:

~/d/p/parinfer-test (master)> lein with-profile bench run
Evaluation count : 1380 in 60 samples of 23 calls.
             Execution time mean : 45.121138 ms
    Execution time std-deviation : 446.875947 µs
   Execution time lower quantile : 44.435676 ms ( 2.5%)
   Execution time upper quantile : 46.004253 ms (97.5%)
                   Overhead used : 1.672151 ns
Evaluation count : 1380 in 60 samples of 23 calls.
             Execution time mean : 45.253843 ms
    Execution time std-deviation : 1.039081 ms
   Execution time lower quantile : 44.084716 ms ( 2.5%)
   Execution time upper quantile : 47.587892 ms (97.5%)
                   Overhead used : 1.672151 ns

Found 3 outliers in 60 samples (5.0000 %)
	low-severe	 3 (5.0000 %)
 Variance from outliers : 10.9943 % Variance is moderately inflated by outliers

cfleming23:02:47

I saw there’s some spots that I can optimise there, too, I’ll do that now.

cfleming23:02:28

Those two results are indent mode and paren mode on really_long_file