Hi Andy, Thanks! I just tried out the master branch of guile in git (the one tagged v2.9.2). It now passes all of my unit tests. So that's good! ... More or less -- there's still some infrequent multi-threading bug(s). Let me describe. My unit test just transitions C->guile->C and returns, in rapid succession, in 20 threads. So, in pseudocode: SCM do_stuff(SCM a, SCM b) { scm_to_utf8_string(a); scm_to_int(b); ... minor stuff... return scm_from_int(...); } scm_c_define_gsubr("do-things",2,0,0, do_stuff); void thing_doer(int thread_id) { for (i=0; i=15000; i++) char str[100]; sprintf(str, "(do-things foo %d)", i); scm_c_catch(scm_eval_string, str); } main () { for (int i=1; i<15; i++) // start 15 threads std::thread(&thing_doer, i); } I'm guessing the above code spends maybe 90% of its time bouncing between guile and C. The string "(do-things foo 42)" changes each time in the loop, so, not sure how the compile vs. interpret tradeoff is done. Either way, its relatively trivial. Likewise, the do_stuff() C routine is fairly thin; after decoding it's args, it doesn't do all that much (sub-microsecond of computing). Based on old, old measurements, scm_eval_string really is the primary CPU consumer, in the 20-microseconds range. Launching 15 threads means that this thing is racing as fast as it can. Anyway, with guile-2.9.2, the above crashes after about 10-15 minutes, either with memory corruption, or with segfault. I worried, so I retested with guile-2.2.4 ... which also crashes, but much much less frequently: seven times in 44 hours wall-clock time (so once ever 6 hours). Which is still more than desired, but...OK. So where's the crash? No clue. Could be my code, could be guile. Since there's a big difference between guile-2.2 and guile-2.9, I'm ready to blame guile. I did try to run it with `valgrind --tool helgrind` and got an ocean of complaints about guile GC, which are probably harmless. I haven't tried to dig deeper yet. -- Linas On Thu, May 23, 2019 at 2:28 PM Andy Wingo wrote: > Hi! > > On Thu 06 Dec 2018 06:21, Linas Vepstas writes: > > > After sending the email below, I scanned the guile-devel archives, > > and I see Thomas Morley talking about Lilypond performance. > > The example program he offers up caught my eye: nested deep > > in a loop is this: > > > > (eval-string "'(a b c)") > > In this case I believe Guile 2.9 / 3 should be significantly faster than > 2.2, because `eval' is compiled to native code rather than bytecode. My > measurements showed it to be on par with the hand-optimized C > implementation from 1.8 and before. Depends of course on how much the > expander is part of your workload, there are differences relative to > Guile 1.8. Anyway, thanks for the note and I just wanted to mention > this point. > > Regarding Scheme -> C++ transitions, there is the possibility that this > too could be much faster with Guile 2.9.x given that these calls are now > JIT-compiled instead of interpreted. We'll have to see. > > Cheers, > > Andy > -- cassette tapes - analog TV - film cameras - you