Felix gc is now reasonably efficient. However,the world-stop at service call constraint plus some continued inefficiencies in the optimisation process make some functional code impractical.
/////////////////////////////////////////////// //Check garbage collector #import <flx.flxh>; open List; proc collect() { println q"Before collection: nobj=$(gc_get_allocation_count()) amt= $(gc_get_allocation_amt())"; Control::collect(); println q"After collection: nobj=$(gc_get_allocation_count()) amt= $(gc_get_allocation_amt())"; } collect(); var a = list(1,2,3,4); fun conv (a:list[int])=> fold_left (fun (acc: list[int]) (item2:int)=> acc + map (fun (item1:int)=> item1+item2) a ) Empty[int] a ; var x = conv a; Control::collect(); println q"x=$(x)"; collect(); x = conv x; collect(); println q"x=$(x)"; collect(); /* x = conv x; collect(); println q"x=$(x)"; collect(); */ var x_sum = fold_left (fun (acc:int) (item:int)=>acc+item) 0 x; var y = map (fun (item:int)=> item * item) x; var y_sum = fold_left (fun (acc:int) (item:int)=>acc+item) 0 y; println q"x_sum=$x_sum, y_sum=$(y_sum)"; ////////////////////////////////////////////////////////////// This code throws my moronic Linux into a paging frenzy. I have to say Linux sucks totally. I have swapoff, but it still pages. The mouse doesn't move and I can't kill the process except with a hardware reboot. Anyhow, the problem in this code is that although the last 'conv()' call generates a reasonably sized list, the fold/map functions also spawn about 10 times more closures than the number of list elements. The output: ////////////////////// [EMAIL PROTECTED]:/work/felix/svn/felix/felix/trunk$ f test/regress/nd-1.01.01-0.flx //Parsing Implementation std.flx //Parsing Implementation test/regress/nd-1.01.01-0.flx Before collection: nobj=4 amt=232 After collection: nobj=4 amt=232 x=[2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8] Before collection: nobj=150 amt=5752 After collection: nobj=24 amt=712 Before collection: nobj=9183 amt=429192 After collection: nobj=264 amt=6472 x=[4, 5, 6, 7, 5, 6, 7, 8, 6, ........ 6] Before collection: nobj=2311 amt=88368 After collection: nobj=264 amt=6472 x_sum=2560, y_sum=26880 ///////////////////// 264 elements, 0.5Meg Ram, the next pass blows 1G. This test shows the GC works (and it seems fast). However, functional code like this isn't practical because the GC can't be called until the function terminates. I can improve the optimiser .. the generated C++ is crap, hardly any inlining and it didn't tail-rec optimise for unknown reason. But this will not solve the basic problem. There's no way to run a non-world-stop collector. Even a world stop single thread collector is hard because it requires machine dependent finding of the machine stack to scan for roots. There's also no way to actually stop threads that I know of on Posix. [SIGSTOP stops processes .. I think this works on Linux, since a thread is a process] Boehm has a number of platform dependent hacks to solve these things, but there's no point emulating them: we might as well just use Boehm. There IS a solution: get rid of functions. By that I mean forcibly reduce all functions to procedural code. That eliminates the machine stack. But it therefore gets in the way of calling Felix functions inside C fun primitives, since such fragments do use the machine stack. Any suggestions on the way forward appreciated.. :) -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language