--- bench_slow.log Trunk +++ bench_fast.log Patched (split, rsplit, replace) stringbench v2.0_fx 2.7a1+ (trunk:77287M, Jan 4 2010, 14:01:56) [GCC 4.3.4] 2010-01-04 14:02:04.159963 string unicode (in ms) (in ms) % comment ========== case conversion -- dense -5.64 10.66 52.9 ("WHERE IN THE WORLD IS CARMEN SAN DEIGO?"*10).lower() (*1000) -5.72 10.95 52.2 ("where in the world is carmen san deigo?"*10).upper() (*1000) +5.61 10.47 53.6 ("WHERE IN THE WORLD IS CARMEN SAN DEIGO?"*10).lower() (*1000) +5.94 10.87 54.6 ("where in the world is carmen san deigo?"*10).upper() (*1000) ========== case conversion -- rare -3.61 8.95 40.4 ("Where in the world is Carmen San Deigo?"*10).lower() (*1000) -5.92 11.05 53.6 ("wHERE IN THE WORLD IS cARMEN sAN dEIGO?"*10).upper() (*1000) +3.60 9.16 39.3 ("Where in the world is Carmen San Deigo?"*10).lower() (*1000) +6.16 11.02 55.9 ("wHERE IN THE WORLD IS cARMEN sAN dEIGO?"*10).upper() (*1000) ========== concat 20 strings of words length 4 to 15 -8.06 10.39 77.6 s1+s2+s3+s4+...+s20 (*1000) +8.01 10.21 78.4 s1+s2+s3+s4+...+s20 (*1000) ========== concat two strings -0.51 0.56 90.6 "Andrew"+"Dalke" (*1000) +0.51 0.51 99.1 "Andrew"+"Dalke" (*1000) ========== count AACT substrings in DNA example -5.60 5.80 96.6 dna.count("AACT") (*10) +5.80 5.63 103.1 dna.count("AACT") (*10) ========== count newlines -2.61 2.58 101.2 ...text.with.2000.newlines.count("\n") (*10) +2.62 2.63 99.6 ...text.with.2000.newlines.count("\n") (*10) ========== early match, single character -0.20 0.22 92.3 "A" in "A"*1000 (*1000) -0.50 0.52 96.3 ("A"*1000).find("A") (*1000) -0.50 0.51 97.3 ("A"*1000).index("A") (*1000) -1.04 1.16 89.0 ("A"*1000).partition("A") (*1000) -0.53 0.56 96.0 ("A"*1000).rfind("A") (*1000) -0.53 0.56 95.3 ("A"*1000).rindex("A") (*1000) -0.91 1.04 87.2 ("A"*1000).rpartition("A") (*1000) -1.57 1.72 91.0 ("A"*1000).rsplit("A", 1) (*1000) -1.61 1.85 86.8 ("A"*1000).split("A", 1) (*1000) +0.20 0.22 90.6 "A" in "A"*1000 (*1000) +0.49 0.51 95.9 ("A"*1000).find("A") (*1000) +0.49 0.51 94.7 ("A"*1000).index("A") (*1000) +0.99 1.31 75.3 ("A"*1000).partition("A") (*1000) +0.53 0.55 96.3 ("A"*1000).rfind("A") (*1000) +0.52 0.55 93.9 ("A"*1000).rindex("A") (*1000) +0.91 1.06 85.7 ("A"*1000).rpartition("A") (*1000) +1.64 1.70 96.5 ("A"*1000).rsplit("A", 1) (*1000) +1.65 1.95 84.7 ("A"*1000).split("A", 1) (*1000) ========== early match, two characters -0.21 0.24 88.4 "AB" in "AB"*1000 (*1000) -0.51 0.53 96.0 ("AB"*1000).find("AB") (*1000) -0.51 0.53 95.4 ("AB"*1000).index("AB") (*1000) -1.19 1.70 69.6 ("AB"*1000).partition("AB") (*1000) -0.55 0.57 96.3 ("AB"*1000).rfind("AB") (*1000) -0.55 0.58 94.9 ("AB"*1000).rindex("AB") (*1000) -1.04 1.25 82.9 ("AB"*1000).rpartition("AB") (*1000) -1.72 1.96 87.8 ("AB"*1000).rsplit("AB", 1) (*1000) -1.83 2.37 77.3 ("AB"*1000).split("AB", 1) (*1000) +0.21 0.24 88.8 "AB" in "AB"*1000 (*1000) +0.50 0.53 95.0 ("AB"*1000).find("AB") (*1000) +0.51 0.53 95.0 ("AB"*1000).index("AB") (*1000) +1.29 1.69 76.4 ("AB"*1000).partition("AB") (*1000) +0.54 0.57 94.1 ("AB"*1000).rfind("AB") (*1000) +0.53 0.57 93.2 ("AB"*1000).rindex("AB") (*1000) +1.04 1.27 81.8 ("AB"*1000).rpartition("AB") (*1000) +1.74 1.93 90.0 ("AB"*1000).rsplit("AB", 1) (*1000) +1.97 2.37 83.0 ("AB"*1000).split("AB", 1) (*1000) ========== endswith multiple characters -0.50 0.51 96.7 "Andrew".endswith("Andrew") (*1000) +0.49 0.51 96.5 "Andrew".endswith("Andrew") (*1000) ========== endswith multiple characters - not! -0.49 0.50 98.6 "Andrew".endswith("Anders") (*1000) +0.49 0.49 99.7 "Andrew".endswith("Anders") (*1000) ========== endswith single character -0.49 0.51 97.3 "Andrew".endswith("w") (*1000) +0.48 0.50 97.3 "Andrew".endswith("w") (*1000) ========== formatting a string type with a dict -2.63 2.49 105.9 "The %(k1)s is %(k2)s the %(k3)s."%{"k1":"x","k2":"y","k3":"z",} (*1000) +2.70 2.49 108.6 "The %(k1)s is %(k2)s the %(k3)s."%{"k1":"x","k2":"y","k3":"z",} (*1000) ========== join empty string, with 1 character sep -4.05 4.03 100.7 "A".join("") (*1000) +4.02 4.13 97.4 "A".join("") (*1000) ========== join empty string, with 5 character sep -4.04 4.05 99.7 "ABCDE".join("") (*1000) +4.02 4.13 97.4 "ABCDE".join("") (*1000) ========== join list of 100 words, with 1 character sep -3.72 5.28 70.4 "A".join(["Bob"]*100)) (*1000) +3.84 5.55 69.3 "A".join(["Bob"]*100)) (*1000) ========== join list of 100 words, with 5 character sep -3.82 5.68 67.4 "ABCDE".join(["Bob"]*100)) (*1000) +3.81 5.96 64.0 "ABCDE".join(["Bob"]*100)) (*1000) ========== join list of 26 characters, with 1 character sep -1.36 1.85 73.8 "A".join(list("ABC..Z")) (*1000) +1.37 1.90 72.2 "A".join(list("ABC..Z")) (*1000) ========== join list of 26 characters, with 5 character sep -1.39 2.30 60.4 "ABCDE".join(list("ABC..Z")) (*1000) +1.38 2.32 59.7 "ABCDE".join(list("ABC..Z")) (*1000) ========== join string with 26 characters, with 1 character sep -7.00 7.74 90.4 "A".join("ABC..Z") (*1000) +7.04 7.93 88.8 "A".join("ABC..Z") (*1000) ========== join string with 26 characters, with 5 character sep -7.12 8.36 85.2 "ABCDE".join("ABC..Z") (*1000) +7.07 8.49 83.2 "ABCDE".join("ABC..Z") (*1000) ========== late match, 100 characters -8.98 9.17 97.9 s="ABC"*33; (s+"E") in ((s+"D")*300+s+"E") (*100) -14.95 15.29 97.8 s="ABC"*33; ((s+"D")*500+s+"E").find(s+"E") (*100) -10.32 10.48 98.4 s="ABC"*33; ((s+"D")*500+"E"+s).find("E"+s) (*100) -14.93 15.36 97.2 s="ABC"*33; ((s+"D")*500+s+"E").index(s+"E") (*100) -16.05 17.50 91.7 s="ABC"*33; ((s+"D")*500+s+"E").partition(s+"E") (*100) -11.83 11.96 98.9 s="ABC"*33; ("E"+s+("D"+s)*500).rfind("E"+s) (*100) -8.81 9.24 95.4 s="ABC"*33; (s+"E"+("D"+s)*500).rfind(s+"E") (*100) -11.83 11.93 99.2 s="ABC"*33; ("E"+s+("D"+s)*500).rindex("E"+s) (*100) -13.23 14.14 93.6 s="ABC"*33; ("E"+s+("D"+s)*500).rpartition("E"+s) (*100) -13.30 20.51 64.8 s="ABC"*33; ("E"+s+("D"+s)*500).rsplit("E"+s, 1) (*100) -16.12 29.88 54.0 s="ABC"*33; ((s+"D")*500+s+"E").split(s+"E", 1) (*100) +8.94 9.18 97.3 s="ABC"*33; (s+"E") in ((s+"D")*300+s+"E") (*100) +14.91 15.25 97.8 s="ABC"*33; ((s+"D")*500+s+"E").find(s+"E") (*100) +10.60 10.46 101.3 s="ABC"*33; ((s+"D")*500+"E"+s).find("E"+s) (*100) +14.91 15.25 97.8 s="ABC"*33; ((s+"D")*500+s+"E").index(s+"E") (*100) +16.04 17.48 91.8 s="ABC"*33; ((s+"D")*500+s+"E").partition(s+"E") (*100) +11.77 12.05 97.7 s="ABC"*33; ("E"+s+("D"+s)*500).rfind("E"+s) (*100) +8.80 9.34 94.2 s="ABC"*33; (s+"E"+("D"+s)*500).rfind(s+"E") (*100) +11.78 12.05 97.7 s="ABC"*33; ("E"+s+("D"+s)*500).rindex("E"+s) (*100) +13.14 14.28 92.0 s="ABC"*33; ("E"+s+("D"+s)*500).rpartition("E"+s) (*100) +13.27 14.38 92.2 s="ABC"*33; ("E"+s+("D"+s)*500).rsplit("E"+s, 1) (*100) +16.19 17.61 91.9 s="ABC"*33; ((s+"D")*500+s+"E").split(s+"E", 1) (*100) ========== late match, two characters -2.17 2.20 98.5 "BC" in ("AB"*300+"C") (*1000) -2.50 2.54 98.4 ("AB"*300+"C").find("BC") (*1000) -3.15 3.16 99.6 ("AB"*300+"CA").find("CA") (*1000) -2.51 2.53 99.2 ("AB"*300+"C").index("BC") (*1000) -2.85 2.98 95.8 ("AB"*300+"C").partition("BC") (*1000) -2.12 2.19 96.7 ("C"+"AB"*300).rfind("CA") (*1000) -2.67 2.75 97.1 ("BC"+"AB"*300).rfind("BC") (*1000) -2.11 2.17 97.2 ("C"+"AB"*300).rindex("CA") (*1000) -2.46 2.67 92.0 ("C"+"AB"*300).rpartition("CA") (*1000) -3.10 3.95 78.6 ("C"+"AB"*300).rsplit("CA", 1) (*1000) -3.52 5.32 66.3 ("AB"*300+"C").split("BC", 1) (*1000) +2.17 2.20 98.7 "BC" in ("AB"*300+"C") (*1000) +2.49 2.54 98.3 ("AB"*300+"C").find("BC") (*1000) +3.14 3.17 99.2 ("AB"*300+"CA").find("CA") (*1000) +2.51 2.53 99.2 ("AB"*300+"C").index("BC") (*1000) +2.86 2.98 95.9 ("AB"*300+"C").partition("BC") (*1000) +2.11 2.17 97.2 ("C"+"AB"*300).rfind("CA") (*1000) +2.66 2.76 96.3 ("BC"+"AB"*300).rfind("BC") (*1000) +2.09 2.16 96.9 ("C"+"AB"*300).rindex("CA") (*1000) +2.48 2.72 91.1 ("C"+"AB"*300).rpartition("CA") (*1000) +3.14 3.54 88.7 ("C"+"AB"*300).rsplit("CA", 1) (*1000) +3.55 3.65 97.3 ("AB"*300+"C").split("BC", 1) (*1000) ========== no match, single character -3.49 3.50 99.7 "B" in "A"*1000 (*1000) -3.78 3.79 99.6 ("A"*1000).find("B") (*1000) -3.67 3.62 101.5 ("A"*1000).partition("B") (*1000) -3.70 3.62 102.1 ("A"*1000).rfind("B") (*1000) -3.59 3.48 103.3 ("A"*1000).rpartition("B") (*1000) -3.63 4.39 82.7 ("A"*1000).rsplit("B", 1) (*1000) -3.87 4.64 83.5 ("A"*1000).split("B", 1) (*1000) +3.48 3.51 99.2 "B" in "A"*1000 (*1000) +3.77 3.80 99.4 ("A"*1000).find("B") (*1000) +3.67 3.63 101.1 ("A"*1000).partition("B") (*1000) +3.69 3.62 102.1 ("A"*1000).rfind("B") (*1000) +3.58 3.45 103.7 ("A"*1000).rpartition("B") (*1000) +3.70 3.67 101.0 ("A"*1000).rsplit("B", 1) (*1000) +3.89 3.90 99.7 ("A"*1000).split("B", 1) (*1000) ========== no match, two characters -6.73 6.77 99.3 "BC" in "AB"*1000 (*1000) -7.02 7.11 98.8 ("AB"*1000).find("BC") (*1000) -9.25 9.18 100.8 ("AB"*1000).find("CA") (*1000) -6.87 6.90 99.5 ("AB"*1000).partition("BC") (*1000) -7.71 7.93 97.2 ("AB"*1000).rfind("BC") (*1000) -5.85 6.00 97.4 ("AB"*1000).rfind("CA") (*1000) -7.60 7.82 97.1 ("AB"*1000).rpartition("BC") (*1000) -8.91 13.05 68.2 ("AB"*1000).rsplit("BC", 1) (*1000) -8.23 13.97 58.9 ("AB"*1000).split("BC", 1) (*1000) +6.71 6.86 97.9 "BC" in "AB"*1000 (*1000) +7.02 7.07 99.2 ("AB"*1000).find("BC") (*1000) +9.18 9.14 100.4 ("AB"*1000).find("CA") (*1000) +6.96 6.94 100.3 ("AB"*1000).partition("BC") (*1000) +7.68 7.97 96.4 ("AB"*1000).rfind("BC") (*1000) +5.89 6.01 98.0 ("AB"*1000).rfind("CA") (*1000) +7.59 7.79 97.4 ("AB"*1000).rpartition("BC") (*1000) +8.14 8.42 96.7 ("AB"*1000).rsplit("BC", 1) (*1000) +7.48 7.52 99.5 ("AB"*1000).split("BC", 1) (*1000) ========== quick replace multiple character match -4.51 159.78 2.8 ("A" + ("Z"*128*1024)).replace("AZZ", "BBZZ", 1) (*100) +3.67 7.30 50.3 ("A" + ("Z"*128*1024)).replace("AZZ", "BBZZ", 1) (*100) ========== quick replace single character match -3.73 50.61 7.4 ("A" + ("Z"*128*1024)).replace("A", "BB", 1) (*100) +3.72 7.18 51.9 ("A" + ("Z"*128*1024)).replace("A", "BB", 1) (*100) ========== repeat 1 character 10 times -0.58 0.65 89.2 "A"*10 (*1000) +0.58 0.64 89.9 "A"*10 (*1000) ========== repeat 1 character 1000 times -0.75 3.44 21.7 "A"*1000 (*1000) +0.76 3.34 22.7 "A"*1000 (*1000) ========== repeat 5 characters 10 times -0.63 0.66 95.4 "ABCDE"*10 (*1000) +0.62 0.64 98.0 "ABCDE"*10 (*1000) ========== repeat 5 characters 1000 times -1.36 1.87 72.8 "ABCDE"*1000 (*1000) +1.35 1.84 73.4 "ABCDE"*1000 (*1000) ========== replace and expand multiple characters, big string -1.54 7.03 21.9 "...text.with.2000.newlines...replace("\n", "\r\n") (*10) +1.53 6.64 23.0 "...text.with.2000.newlines...replace("\n", "\r\n") (*10) ========== replace multiple characters, dna -7.18 8.89 80.8 dna.replace("ATC", "ATT") (*10) +7.74 7.95 97.3 dna.replace("ATC", "ATT") (*10) ========== replace single character -0.97 1.06 91.6 "This is a test".replace(" ", "\t") (*1000) +0.97 1.05 93.1 "This is a test".replace(" ", "\t") (*1000) ========== replace single character, big string -5.40 31.64 17.1 "...text.with.2000.lines...replace("\n", " ") (*100) +5.38 31.03 17.3 "...text.with.2000.lines...replace("\n", " ") (*100) ========== replace/remove multiple characters -1.28 1.30 98.3 "When shall we three meet again?".replace("ee", "") (*1000) +1.28 1.31 97.9 "When shall we three meet again?".replace("ee", "") (*1000) ========== split 1 whitespace -1.09 0.84 129.7 ("Here are some words. "*2).partition(" ") (*1000) -0.72 0.76 95.4 ("Here are some words. "*2).rpartition(" ") (*1000) -1.81 1.89 96.0 ("Here are some words. "*2).rsplit(None, 1) (*1000) -1.74 1.54 113.0 ("Here are some words. "*2).split(None, 1) (*1000) +1.10 0.87 126.5 ("Here are some words. "*2).partition(" ") (*1000) +0.72 0.77 94.2 ("Here are some words. "*2).rpartition(" ") (*1000) +1.80 1.83 98.3 ("Here are some words. "*2).rsplit(None, 1) (*1000) +1.74 1.46 118.9 ("Here are some words. "*2).split(None, 1) (*1000) ========== split 2000 newlines -11.07 14.58 75.9 "...text...".rsplit("\n") (*10) -10.95 14.69 74.5 "...text...".split("\n") (*10) -11.59 15.64 74.1 "...text...".splitlines() (*10) +11.09 14.46 76.7 "...text...".rsplit("\n") (*10) +11.11 14.55 76.4 "...text...".split("\n") (*10) +11.61 15.43 75.3 "...text...".splitlines() (*10) ========== split newlines -2.08 1.78 117.1 "this\nis\na\ntest\n".rsplit("\n") (*1000) -2.06 1.76 117.0 "this\nis\na\ntest\n".split("\n") (*1000) -1.90 1.13 168.7 "this\nis\na\ntest\n".splitlines() (*1000) +2.17 1.36 159.9 "this\nis\na\ntest\n".rsplit("\n") (*1000) +2.11 1.33 159.0 "this\nis\na\ntest\n".split("\n") (*1000) +1.99 1.14 174.3 "this\nis\na\ntest\n".splitlines() (*1000) ========== split on multicharacter separator (dna) -5.59 8.86 63.1 dna.rsplit("ACTAT") (*10) -6.65 8.94 74.3 dna.split("ACTAT") (*10) +5.52 6.01 91.8 dna.rsplit("ACTAT") (*10) +6.71 7.05 95.2 dna.split("ACTAT") (*10) ========== split on multicharacter separator (small) -4.25 4.95 85.8 "this--is--a--test--of--the--emergency--broadcast--system".rsplit("--") (*1000) -4.33 4.80 90.2 "this--is--a--test--of--the--emergency--broadcast--system".split("--") (*1000) +4.37 4.08 107.0 "this--is--a--test--of--the--emergency--broadcast--system".rsplit("--") (*1000) +4.41 4.02 109.9 "this--is--a--test--of--the--emergency--broadcast--system".split("--") (*1000) ========== split whitespace (huge) -12.69 16.69 76.0 human_text.rsplit() (*10) -12.53 16.89 74.2 human_text.split() (*10) +12.20 16.42 74.3 human_text.rsplit() (*10) +11.87 16.50 71.9 human_text.split() (*10) ========== split whitespace (small) -3.90 3.26 119.8 ("Here are some words. "*2).rsplit() (*1000) -3.94 2.19 180.4 ("Here are some words. "*2).split() (*1000) +3.80 2.69 141.1 ("Here are some words. "*2).rsplit() (*1000) +3.83 1.67 229.7 ("Here are some words. "*2).split() (*1000) ========== startswith multiple characters -0.49 0.52 95.8 "Andrew".startswith("Andrew") (*1000) +0.49 0.51 96.3 "Andrew".startswith("Andrew") (*1000) ========== startswith multiple characters - not! -0.49 0.50 98.9 "Andrew".startswith("Anders") (*1000) +0.49 0.49 98.4 "Andrew".startswith("Anders") (*1000) ========== startswith single character -0.49 0.50 96.6 "Andrew".startswith("A") (*1000) +0.48 0.50 96.5 "Andrew".startswith("A") (*1000) ========== strip terminal newline -0.81 0.51 157.4 s="Hello!\n"; s[:-1] if s[-1]=="\n" else s (*1000) -0.53 0.23 227.9 "\nHello!".rstrip() (*1000) -0.54 0.24 227.7 "Hello!\n".rstrip() (*1000) -0.54 0.24 222.0 "\nHello!\n".strip() (*1000) -0.54 0.24 225.5 "\nHello!".strip() (*1000) -0.54 0.24 225.4 "Hello!\n".strip() (*1000) +0.82 0.53 155.4 s="Hello!\n"; s[:-1] if s[-1]=="\n" else s (*1000) +0.54 0.24 225.3 "\nHello!".rstrip() (*1000) +0.55 0.24 226.7 "Hello!\n".rstrip() (*1000) +0.55 0.25 224.9 "\nHello!\n".strip() (*1000) +0.56 0.24 228.6 "\nHello!".strip() (*1000) +0.55 0.24 227.6 "Hello!\n".strip() (*1000) ========== strip terminal spaces and tabs -0.55 0.25 219.5 "\t \tHello".rstrip() (*1000) -0.56 0.26 217.3 "Hello\t \t".rstrip() (*1000) -0.18 0.18 100.8 "Hello\t \t".strip() (*1000) +0.56 0.26 220.8 "\t \tHello".rstrip() (*1000) +0.57 0.26 219.9 "Hello\t \t".rstrip() (*1000) +0.18 0.18 100.9 "Hello\t \t".strip() (*1000) ========== tab split -3.27 3.52 93.0 GFF3_example.rsplit("\t", 8) (*1000) -3.14 3.40 92.5 GFF3_example.rsplit("\t") (*1000) -3.02 3.45 87.6 GFF3_example.split("\t", 8) (*1000) -3.12 3.33 93.5 GFF3_example.split("\t") (*1000) +3.39 2.61 129.6 GFF3_example.rsplit("\t", 8) (*1000) +3.30 2.51 131.6 GFF3_example.rsplit("\t") (*1000) +3.17 2.36 134.3 GFF3_example.split("\t", 8) (*1000) +3.27 2.48 131.5 GFF3_example.split("\t") (*1000) ========== -513.54 854.36 60.1 TOTAL +513.36 610.21 84.1 TOTAL