I wrote a patch to Ruby 1.6.0pre2's gc.c that makes gc frequency inversely
proportional to the number of currently allocated objects, so that % of
time spent on GC remains about the same. With Aleksi's program (see
message #4407) I get the following results. My version of the GC uses
about 20% more RAM, but one can fumble with the linear equations for more
conservative RAM usage if wanted.

Aleksi's program with original ruby 1.6.0pre2 garbage collector:

      0: 02:28:30.884
   1000: 02:28:31.977 1.0938
   2000: 02:28:33.926 1.9487
   3000: 02:28:36.772 2.8460
   4000: 02:28:40.610 3.8377
   5000: 02:28:45.309 4.6988
[...]
  20000: 02:31:46.021 18.6758
  21000: 02:32:04.996 18.9755
  22000: 02:32:24.899 19.9027
  23000: 02:32:45.754 20.8553
  24000: 02:33:08.305 22.5503

With my patch:

      0: 02:24:37.112
   1000: 02:24:38.061 0.9497
   2000: 02:24:39.134 1.0725
   3000: 02:24:40.323 1.1893
   4000: 02:24:41.468 1.1449
   5000: 02:24:42.816 1.3479
[...]
  20000: 02:25:03.431 1.1860
  21000: 02:25:04.710 1.2786
  22000: 02:25:05.992 1.2823
  23000: 02:25:08.051 2.0590
  24000: 02:25:09.388 1.3363



Here is the patch (it's not beautiful, but it works):

51,69d50
< long allocated_cells = 0;
< 
< int
< gc_enough_mallocs_p()
< {
< 	return malloc_memories > 1000000 + (allocated_cells<<7);
< }
< 
< int
< gc_free_min()
< {
< 	return 4096 + (allocated_cells>>3);
< }
< 
< int
< gc_heaps_increment()
< {
< 	return 8 + (allocated_cells>>16);
< }
92c73
<     if (gc_enough_mallocs_p()) {
---
>     if (malloc_memories > GC_MALLOC_LIMIT) {
273c254
< 	heaps_length += gc_heaps_increment();
---
> 	heaps_length += HEAPS_INCREMENT;
305d285
<     allocated_cells++;
714c694
<     while (freed < gc_free_min()) {
---
>     if (freed < FREE_MIN) {
716d695
< 	freed += HEAP_SLOTS;
858d836
<     allocated_cells--;
923c901
< 	if (!freelist || gc_enough_mallocs_p()) {
---
> 	if (!freelist || malloc_memories > GC_MALLOC_LIMIT) {
1260,1265d1237
< static VALUE
< gc_allocated_cells()
< {
< 	return INT2NUM(allocated_cells);
< }
< 
1272d1243
<     rb_define_singleton_method(rb_mGC, "allocated_cells", gc_allocated_cells, 0);




matju