develooper Front page | perl.perl5.porters | Postings from June 2021

Re: Benchmarking Pure Perl Trim Functions.

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
June 3, 2021 19:36
Subject:
Re: Benchmarking Pure Perl Trim Functions.
Message ID:
20210603193618.GS9170@etla.org
On Tue, Jun 01, 2021 at 08:59:03AM +0200, demerphq wrote:

> I put the following together. It benchmarks various techniques for trimming
> strings at different string lengths and composition.

Cool, thanks.

> It produces the following report. The left side shows the composition of
> the string, and its length. The next column is timing for the naive
> s/\A\s+|\s+\z//g approach. The following four columns contain data for each
> other comparison strategy. "separate" is standard recommended "less worse
> way" of using two s/\A\s+// and s/\s+\z//. The rest are solutions I ginned
> up knowing how the  regex engine works to optimize the separate strategy.
> The strategy that is the +best+  for any row is prefixed with a + sign.

These are strategies I would never have considered - thanks for the insight.

> "separate" function to be run time proportional to the length as well. What
> all this shows is that a properly implemented trim/trim function in XS
> would be *massively* faster than all of this.It would be able to do a very
> low overhead walk from the right to ensure that the performance is
> completely dominated by the number of spaces it needs to remove which I
> guess would be as efficient it can be made to be.

I came up with this:

            while (1) {
                const char *was_s = s;
                if (s == strpos)
                    break;
                s = (const char *) Perl_utf8_hop_back((const U8 *)s, -1, (const U8 *)strpos);
                if (s < strpos || !isSPACE_utf8_safe(s, strend)) {
                    s = was_s;
                    break;
                }
            }

[with 8-bit variants for !isSPACE(*s) and !isSPACE_L1(*s)]

I'm still thinking that there ought to be a more elegant way to express
the two `if`s and the (effective) backtracking of the `s = was_s`, but
I can't see it.

> I note that if you consider rtrimming sentences, most fo the sentences in
> this mail would be of a type and structure that most users would benefit
> from using the loop2 strategy, not the commonly recommended separate
> strategy.

Yes, this is quite an eye-opener. Thanks for making me think.

So I took your ideas and tried to implement them.

More - I assumed that the regexes used to "trim spaces from the right" are

1) simple to recognise
2) there aren't that many variations of them

So I set off with the goal of recognising them in the regex compiler, and
then having re_intuit_start() implement them better.

In the branch https://github.com/nwc10/perl5/tree/intiuit-rtrim

(if I have this right) regcomp.c recognises all patterns of the form

   { PLUS , STAR } { POSIXU[\s] , POSIXD[\d] } { EOS , SEOL } END

ie

   /\s+$/
   /\s+\z/
   /\s+$/u
   /\s+\z/u

and with * instead of +
(These days, [[:space:]] is \s, so that's covered too)


and regexec.c matches these efficiently starting from the end of the string.

If I understand this correctly, it isn't totally generalisable to "matching
in reverse", at least not easily (fixed width, or one greedy match) because
in this case

   for /\s+$/ both /\s+/ and /$/ are variable width
   but because /\s+$/ is effectively /\s+\n?\z/
   and \n is part of the class \s
   we can eliminate \n?
   getting us to /\s+\z/

which is easy to run in reverse, and doesn't backtrack ("forwardtrack"?)


Anyway, I ran your benchmarks against it:

reps  ns  sp        len|     naive|  separate     as pct|      loop     as pct| loop_chop     as pct|     loop2     as pct|
-----------------------+----------+---------------------+---------------------+---------------------+---------------------+
   1   1   1          3| 1003690.9|+1113130.0     +110.9|  712513.8       71.0|  667763.9       66.5|  652929.7       65.1|
   1   1   2          5|  990465.9|+1100682.3     +111.1|  523228.6       52.8|  522814.7       52.8|  628417.3       63.4|
   1   1   5         11| 1001701.1|+1102864.4     +110.1|  292535.4       29.2|  321753.0       32.1|  496744.6       49.6|
   1   1  10         21|  996332.8|+1026238.2     +103.0|  166753.8       16.7|  188127.1       18.9|  475441.6       47.7|
   1   1  25         51| +974412.6|  958821.1       98.4|   70433.3        7.2|   86395.7        8.9|  377091.7       38.7|
   1   1 100        201| +874699.0|  833294.3       95.3|   18074.5        2.1|   24223.6        2.8|  188026.0       21.5|
   1   2   1          4|  909935.2|+1111119.9     +122.1|  709812.3       78.0|  661379.5       72.7|  658296.4       72.3|
   1   2   2          6|  897650.7|+1113217.6     +124.0|  522643.4       58.2|  514531.6       57.3|  586765.1       65.4|
   1   2   5         12|  884091.4| +975138.5     +110.3|  289300.7       32.7|  310588.2       35.1|  484564.9       54.8|
   1   2  10         22|  920730.7|+1035058.7     +112.4|  165761.6       18.0|  189035.6       20.5|  451677.3       49.1|
   1   2  25         52|  904542.0| +963969.9     +106.6|   70634.5        7.8|   86737.0        9.6|  376839.8       41.7|
   1   2 100        202|  807114.9| +837355.2     +103.7|   17996.3        2.2|   24203.0        3.0|  183403.3       22.7|
   1   5   1          7|  726176.2|+1110739.9     +153.0|  725535.5       99.9|  661087.9       91.0|  602122.1       82.9|
   1   5   2          9| 1020523.0|+1186136.1     +116.2|  581570.7       57.0|  565234.1       55.4|  626664.9       61.4|
   1   5   5         15|  733285.2|+1042938.0     +142.2|  281291.7       38.4|  305813.7       41.7|  458376.5       62.5|
   1   5  10         25|  727141.1|+1028611.2     +141.5|  158939.8       21.9|  188587.4       25.9|  457126.3       62.9|
   1   5  25         55|  716586.6| +955610.1     +133.4|   69516.4        9.7|   86701.8       12.1|  348686.2       48.7|
   1   5 100        205|  659236.8| +835977.0     +126.8|   17889.2        2.7|   24387.6        3.7|  171207.3       26.0|
   1  10   1         12|  539091.4|+1010957.9     +187.5|  656888.1      121.9|  731871.7      135.8|  546357.7      101.3|
   1  10   2         14|  542148.2|+1007476.4     +185.8|  484258.5       89.3|  472815.5       87.2|  524782.3       96.8|
   1  10   5         20|  546463.8| +994341.3     +182.0|  267874.3       49.0|  306383.1       56.1|  442522.4       81.0|
   1  10  10         30|  547041.5| +988872.6     +180.8|  155924.9       28.5|  188634.6       34.5|  405603.0       74.1|
   1  10  25         60|  539135.6| +923883.2     +171.4|   69141.8       12.8|   87345.4       16.2|  311757.8       57.8|
   1  10 100        210|  504959.9| +808303.4     +160.1|   17538.3        3.5|   24412.1        4.8|  169319.9       33.5|
   1  25   1         27|  320310.9| +950596.1     +296.8|  629869.3      196.6|  718389.9      224.3|  478911.2      149.5|
   1  25   2         29|  319985.6| +948728.2     +296.5|  469684.4      146.8|  482698.3      150.9|  469070.7      146.6|
   1  25   5         35|  322689.0| +892289.0     +276.5|  268205.3       83.1|  313064.8       97.0|  394188.9      122.2|
   1  25  10         45|  321842.4| +926002.1     +287.7|  156897.8       48.7|  192949.7       60.0|  396619.0      123.2|
   1  25  25         75|  319636.4| +902389.8     +282.3|   69378.8       21.7|   89636.5       28.0|  304142.2       95.2|
   1  25 100        225|  306474.1| +718840.8     +234.6|   17521.0        5.7|   24544.0        8.0|  155921.8       50.9|
   1 100   1        102|  107562.8| +848547.6     +788.9|  583851.5      542.8|  720868.6      670.2|  448055.9      416.6|
   1 100   2        104|  106627.1| +821922.4     +770.8|  438928.5      411.6|  464326.2      435.5|  441638.8      414.2|
   1 100   5        110|  106792.6| +836917.0     +783.7|  241029.3      225.7|  304487.1      285.1|  356727.7      334.0|
   1 100  10        120|  106981.3| +884446.8     +826.7|  138200.1      129.2|  188117.9      175.8|  380930.9      356.1|
   1 100  25        150|  107641.7| +853730.2     +793.1|   60698.1       56.4|   88785.2       82.5|  280484.1      260.6|
   1 100 100        300|  106263.3| +723355.2     +680.7|   15877.9       14.9|   24164.9       22.7|  147776.9      139.1|
  10   1   1         21|  362072.0| +978057.7     +270.1|  656784.2      181.4|  724028.8      200.0|  492043.7      135.9|
  10   1   2         32|  271697.1| +936424.7     +344.7|  471022.5      173.4|  478432.9      176.1|  463777.9      170.7|
  10   1   5         65|  155803.0| +929128.2     +596.3|  265646.1      170.5|  309883.3      198.9|  395126.2      253.6|
  10   1  10        120|   90090.0| +822515.8     +913.0|  142389.5      158.1|  191897.6      213.0|  364423.5      404.5|
  10   1  25        285|   36999.4| +758913.2    +2051.1|   59238.7      160.1|   86843.1      234.7|  262869.5      710.5|
  10   1 100       1110|    7777.0| +639082.7    +8217.6|   12826.6      164.9|   22749.6      292.5|  125908.3     1619.0|
  10   2   1         31|  268092.2| +950726.5     +354.6|  640084.3      238.8|  727862.7      271.5|  477444.9      178.1|
  10   2   2         42|  215882.7| +955483.7     +442.6|  468420.6      217.0|  472943.8      219.1|  463272.4      214.6|
  10   2   5         75|  135731.4| +945047.2     +696.3|  265790.9      195.8|  309500.0      228.0|  395545.1      291.4|
  10   2  10        130|   83247.8| +835837.0    +1004.0|  135492.4      162.8|  189524.0      227.7|  374883.8      450.3|
  10   2  25        295|   35665.3| +764128.4    +2142.5|   59462.3      166.7|   87140.9      244.3|  267510.7      750.1|
  10   2 100       1120|    7720.9| +643190.7    +8330.5|   12797.4      165.8|   22832.9      295.7|  125253.2     1622.3|
  10   5   1         61|  159995.4| +951719.0     +594.8|  649259.8      405.8|  724267.6      452.7|  477853.0      298.7|
  10   5   2         72|  140118.5| +935671.8     +667.8|  466523.7      332.9|  477597.2      340.9|  465664.2      332.3|
  10   5   5        105|  101664.6| +837628.7     +823.9|  254422.3      250.3|  306449.2      301.4|  367849.0      361.8|
  10   5  10        160|   68558.6| +870336.8    +1269.5|  138109.3      201.4|  183029.0      267.0|  354533.6      517.1|
  10   5  25        325|   32743.8| +755782.7    +2308.2|   59038.4      180.3|   85755.4      261.9|  264079.3      806.5|
  10   5 100       1150|    7573.7| +631498.9    +8338.1|   12899.4      170.3|   21500.8      283.9|  127344.1     1681.4|
  10  10   1        111|   95824.1| +852424.3     +889.6|  587633.9      613.2|  693153.5      723.4|  450226.5      469.8|
  10  10   2        122|   88437.3| +846479.1     +957.2|  423208.2      478.5|  464149.7      524.8|  439821.6      497.3|
  10  10   5        155|   70747.2| +832122.4    +1176.2|  233055.2      329.4|  291939.9      412.7|  361826.8      511.4|
  10  10  10        210|   53432.5| +818168.8    +1531.2|  136359.3      255.2|  184151.4      344.6|  351738.4      658.3|
  10  10  25        375|   28822.0| +767121.9    +2661.6|   59533.2      206.6|   86358.9      299.6|  265294.4      920.5|
  10  10 100       1200|    7326.2| +645491.8    +8810.7|   12669.8      172.9|   18770.3      256.2|  122905.9     1677.6|
  10  25   1        261|   43817.4| +799756.8    +1825.2|  586361.7     1338.2|  673756.8     1537.6|  431884.3      985.6|
  10  25   2        272|   42309.0| +805735.5    +1904.4|  408213.8      964.8|  456803.7     1079.7|  431699.1     1020.3|
  10  25   5        305|   37789.2| +787450.4    +2083.8|  232726.2      615.9|  287752.3      761.5|  340376.3      900.7|
  10  25  10        360|   32019.5| +813384.3    +2540.3|  133512.1      417.0|  181959.1      568.3|  357928.8     1117.8|
  10  25  25        525|   21310.9| +782197.0    +3670.4|   58363.9      273.9|   85358.7      400.5|  259165.3     1216.1|
  10  25 100       1350|    6725.7| +645953.1    +9604.3|   11936.8      177.5|   17319.4      257.5|  116960.4     1739.0|
  10 100   1       1011|   11809.3| +725670.8    +6144.9|  517029.4     4378.2|  615547.0     5212.4|  409429.1     3467.0|
  10 100   2       1022|   11721.7| +724232.6    +6178.6|  381165.0     3251.8|  414482.7     3536.0|  396596.8     3383.4|
  10 100   5       1055|   11479.2| +700622.2    +6103.4|  193611.6     1686.6|  234019.2     2038.6|  318668.9     2776.1|
  10 100  10       1110|   10777.8| +714691.7    +6631.1|  116234.1     1078.5|  142118.5     1318.6|  315594.0     2928.2|
  10 100  25       1275|    9217.4| +696545.8    +7556.8|   44512.5      482.9|   65640.8      712.1|  230324.3     2498.8|
  10 100 100       2100|    4738.5| +631382.1   +13324.4|   13369.8      282.2|   16669.3      351.8|  125697.7     2652.7|
 100   1   1        201|   52580.8| +804582.2    +1530.2|  587934.0     1118.2|  673257.7     1280.4|  438902.8      834.7|
 100   1   2        302|   34648.7| +791969.1    +2285.7|  403745.4     1165.3|  444464.7     1282.8|  414596.7     1196.6|
 100   1   5        605|   16967.0| +760774.6    +4483.8|  220493.2     1299.5|  288250.8     1698.9|  345578.1     2036.8|
 100   1  10       1110|    9048.6| +685376.2    +7574.4|  103803.0     1147.2|  140017.6     1547.4|  314603.0     3476.8|
 100   1  25       2625|    3504.3| +646897.0   +18460.0|   47960.3     1368.6|   60669.1     1731.3|  227017.2     6478.2|
 100   1 100      10200|     708.7| +417298.7   +58882.0|   10438.8     1472.9|   12858.7     1814.4|   86693.6    12232.7|
 100   2   1        301|   34769.9| +819193.4    +2356.0|  561338.7     1614.4|  670608.8     1928.7|  426010.5     1225.2|
 100   2   2        402|   25795.4| +766480.7    +2971.4|  394262.1     1528.4|  430261.2     1668.0|  409649.4     1588.1|
 100   2   5        705|   14600.9| +759350.9    +5200.7|  236261.9     1618.1|  278647.1     1908.4|  345479.4     2366.1|
 100   2  10       1210|    8307.4| +710528.8    +8553.0|  111069.7     1337.0|  144356.0     1737.7|  315260.1     3794.9|
 100   2  25       2725|    3410.2| +670630.3   +19665.6|   46884.9     1374.9|   61231.6     1795.6|  228665.4     6705.4|
 100   2 100      10300|     709.6| +442275.9   +62324.6|   10506.4     1480.5|   13023.0     1835.2|   86549.6    12196.4|
 100   5   1        601|   18807.7| +807868.8    +4295.4|  558586.3     2970.0|  646406.4     3436.9|  425479.6     2262.3|
 100   5   2        702|   15877.1| +759312.1    +4782.4|  378857.4     2386.2|  436837.3     2751.4|  404711.7     2549.0|
 100   5   5       1005|   10767.5| +736509.4    +6840.1|  188889.0     1754.2|  269362.1     2501.6|  324034.4     3009.4|
 100   5  10       1510|    6917.1| +700177.6   +10122.4|  112900.5     1632.2|  138431.5     2001.3|  313162.3     4527.4|
 100   5  25       3025|    3141.7| +632229.0   +20123.8|   46539.6     1481.4|   59039.4     1879.2|  213271.5     6788.4|
 100   5 100      10600|     696.5| +409337.3   +58767.8|   10282.1     1476.2|   12747.6     1830.1|   85741.0    12309.7|
 100  10   1       1101|   10588.7| +681805.6    +6439.0|  467428.8     4414.4|  561019.2     5298.3|  406696.9     3840.9|
 100  10   2       1202|    9453.4| +695171.4    +7353.6|  339765.7     3594.1|  384120.6     4063.3|  380892.5     4029.1|
 100  10   5       1505|    7418.4| +720197.2    +9708.2|  178909.3     2411.7|  226672.8     3055.5|  311068.3     4193.2|
 100  10  10       2010|    5368.8| +683785.8   +12736.3|  105917.3     1972.8|  137442.2     2560.0|  315562.1     5877.7|
 100  10  25       3525|    2773.3| +622716.6   +22454.3|   40018.5     1443.0|   58528.3     2110.5|  217359.9     7837.7|
 100  10 100      11100|     675.3| +432116.8   +63986.5|    7414.2     1097.9|   12098.1     1791.5|   74683.3    11058.9|
 100  25   1       2601|    4582.1| +677481.3   +14785.3|  439848.7     9599.2|  460887.0    10058.3|  390709.0     8526.8|
 100  25   2       2702|    4406.2| +681993.9   +15478.2|  306663.4     6959.9|  366190.2     8310.9|  369184.4     8378.8|
 100  25   5       3005|    3889.9| +650236.0   +16715.8|  179346.9     4610.5|  215085.3     5529.3|  299620.2     7702.4|
 100  25  10       3510|    3238.9| +621716.1   +19195.4|   92084.2     2843.1|  130538.4     4030.4|  279362.8     8625.3|
 100  25  25       5025|    2071.4| +610553.4   +29475.9|   43993.9     2123.9|   55823.5     2695.0|  204433.2     9869.5|
 100  25 100      12600|     625.7| +335126.6   +53557.3|    6152.9      983.3|   11717.2     1872.6|   88832.3    14196.5|
 100 100   1      10101|    1198.4| +443884.9   +37038.9|  315165.2    26298.2|  351914.4    29364.7|  299202.5    24966.2|
 100 100   2      10202|    1187.7| +452863.5   +38131.0|  239072.4    20129.9|  285951.3    24077.1|  295275.2    24862.1|
 100 100   5      10505|    1139.3| +451448.0   +39624.7|  111783.1     9811.5|  168497.9    14789.5|  213627.5    18750.6|
 100 100  10      11010|    1080.8| +379067.5   +35072.0|   63204.9     5847.8|   98344.5     9099.0|  205100.2    18976.2|
 100 100  25      12525|     911.2| +384162.6   +42160.7|   34897.8     3829.9|   41778.1     4585.0|  132498.6    14541.3|
 100 100 100      20100|     449.1| +309577.1   +68934.3|    6843.7     1523.9|    7575.6     1686.9|   64587.8    14381.9|
1000   1   1       2001|    5513.2| +705964.7   +12805.0|  443004.5     8035.4|  462820.5     8394.8|  396660.9     7194.8|
1000   1   2       3002|    3560.8| +654171.4   +18371.4|  319025.6     8959.3|  366448.2    10291.1|  367123.8    10310.1|
1000   1   5       6005|    1699.0| +584030.2   +34374.8|  142617.4     8394.2|  191861.3    11292.6|  253057.5    14894.5|
1000   1  10      11010|     905.6| +387276.1   +42764.6|   71713.3     7918.9|   92462.6    10210.1|  218586.8    24137.2|
1000   1  25      26025|     351.0| +271720.6   +77410.6|   19063.3     5431.0|   22358.2     6369.7|   92276.5    26288.7|
1000   1 100     101100|      71.1|  +26474.8   +37254.9|    1576.1     2217.8|    1812.6     2550.6|    7318.9    10299.0|
1000   2   1       3001|    3644.8| +668146.9   +18331.6|  441852.9    12122.9|  454139.7    12460.0|  383729.9    10528.2|
1000   2   2       4002|    2685.5| +590297.4   +21980.5|  312197.4    11625.1|  340585.6    12682.2|  367954.9    13701.3|
1000   2   5       7005|    1487.1| +570606.4   +38370.5|  151929.6    10216.5|  185249.8    12457.2|  260425.0    17512.3|
1000   2  10      12010|     837.2| +456634.9   +54541.5|   78853.3     9418.4|   93514.5    11169.6|  199510.5    23830.0|
1000   2  25      27025|     337.7| +214186.1   +63432.4|   12115.8     3588.2|   20982.4     6214.0|   75445.4    22343.6|
1000   2 100     102100|      70.3|  +25851.8   +36782.3|    1606.9     2286.3|    1503.0     2138.4|   10243.6    14574.8|
1000   5   1       6001|    1912.5| +557706.0   +29160.4|  373165.4    19511.5|  412981.4    21593.3|  345404.0    18059.9|
1000   5   2       7002|    1612.9| +518142.8   +32124.2|  284513.7    17639.5|  310736.9    19265.3|  318466.4    19744.5|
1000   5   5      10005|    1081.7| +458660.6   +42401.7|  117417.4    10854.9|  168434.1    15571.2|  223924.7    20701.1|
1000   5  10      15010|     688.5| +375281.2   +54505.5|   70282.7    10207.8|   82576.0    11993.3|  188673.1    27402.7|
1000   5  25      30025|     313.9| +234482.5   +74710.5|   17677.7     5632.4|   19801.7     6309.2|   76560.9    24393.7|
1000   5 100     105100|      69.3|  +25507.5   +36793.8|    1529.8     2206.8|    1752.5     2528.0|    7295.5    10523.5|
1000  10   1      11001|    1073.9| +430805.1   +40115.0|  346739.6    32287.1|  352451.4    32819.0|  279801.8    26054.1|
1000  10   2      12002|     972.3| +452078.7   +46497.0|  212260.8    21831.4|  262182.2    26965.9|  257783.3    26513.4|
1000  10   5      15005|     742.2| +396191.6   +53377.5|   88263.7    11891.4|  136228.7    18353.6|  172361.1    23221.6|
1000  10  10      20010|     539.1| +281071.4   +52133.1|   56946.0    10562.3|   63803.3    11834.2|  144340.1    26772.2|
1000  10  25      35025|     276.1| +141760.4   +51352.1|   15896.0     5758.2|   17414.4     6308.3|   75010.7    27172.3|
1000  10 100     110100|      67.5|  +20708.8   +30699.8|     653.3      968.5|    1581.9     2345.1|    6065.9     8992.3|
1000  25   1      26001|     462.2|  198952.0    43047.1|  209163.4    45256.5| +225044.3   +48692.7|  202981.7    43919.0|
1000  25   2      27002|     442.6| +219574.3   +49607.7|  146194.6    33029.3|  147752.4    33381.2|  168403.6    38046.9|
1000  25   5      30005|     390.9| +235828.7   +60335.3|   45236.6    11573.5|   77708.5    19881.3|   92192.3    23586.8|
1000  25  10      35010|     324.6| +203732.6   +62758.7|   37268.2    11480.3|   40106.1    12354.4|   80063.3    24663.0|
1000  25  25      50025|     206.7| +121929.8   +58987.0|    8724.1     4220.5|   13577.7     6568.6|   45925.6    22217.8|
1000  25 100     125100|      62.3|  +41670.5   +66912.8|     605.2      971.9|    1266.3     2033.3|    5713.6     9174.6|
1000 100   1     101001|     120.1|   54866.4    45672.6|   51591.1    42946.2|  +66803.7   +55609.6|   50671.2    42180.4|
1000 100   2     102002|     119.2|  +68063.5   +57113.9|   32374.3    27166.2|   47701.9    40028.0|   49531.2    41563.0|
1000 100   5     105005|     114.9|  +51774.6   +45077.7|   19059.4    16594.1|   24496.0    21327.5|   34531.5    30065.0|
1000 100  10     110010|     108.2|  +49205.3   +45488.1|   11537.2    10665.6|   13758.5    12719.1|   33275.7    30761.9|
1000 100  25     125025|      91.0|  +54968.4   +60374.7|    2499.2     2745.0|    5211.6     5724.2|   15169.9    16661.9|
1000 100 100     200100|      45.0|  +31219.7   +69398.6|     709.6     1577.4|     719.2     1598.8|    3145.1     6991.3|


*) For all but 4 lines, "separate" is fastest
*) Sometimes up to 60000% (ie SIX HUNDRED TIMES)

So you were right - "a properly implemented trim/trim function in XS would be
*massively* faster than all of this"


But I like the idea of doing it in the regex engine, so that every existing
piece of code writing s/\s+$// goes faster, without any user code changes.

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About