SORU
23 AĞUSTOS 2011, Salı


En hızlı Java bir Dize olmayan yazdırılabilir tüm karakterleri şerit yol

Java String bir sigara-yazdırılabilir tüm karakterleri kaldýrmak için en hızlı yolu nedir?

Bugüne kadar denenmiş ve 138 bayt, 131-karakter Dizesi ölçtüm:

  • Dize replaceAll() -en yavaş yöntem
    • 517009 sonuçları / sn
  • Bir Desen derleme, daha sonra kullanmak Eşleştirici replaceAll()
    • 637836 sonuçları / sn
  • Kullanım StringBuffer, codepoints codepointAt() tek tek kullanarak ve StringBuffer Ekle
    • 711946 sonuçları / sn
  • Kullanım StringBuffer, karakter charAt() tek tek kullanarak ve StringBuffer Ekle
    • 1052964 sonuçları / sn
  • char[] bir tampon önceden ayır, karakter charAt() tek tek kullanarak ve bu tampon dolgu, geri Dize dönüştürmek sonra
    • 2022653 sonuçları / sn
  • Önceden ayır 2 char[] tamponlar - eski ve yeni tüm karakter için varolan Dize aynı anda kullanma getChars(), üzerinde yineleme eski tampon tek tek doldurmak ve yeni bir tampon, yeni tampon dönüştürmek için Dizekendi en hızlı benim sürüm
    • 2502502 sonuçları / sn
  • 2 tamponlar ile aynı şeyler - sadece byte[], getBytes() kullanma ve kodlama belirterek, "utf-8"
    • 857485 sonuçları / sn
  • 2 byte[] tamponlar ile aynı şeyler, ama *18 sürekli*olarak kodlama belirtme
    • 791076 sonuçları / sn
  • 2 byte[] tamponlar ile aynı şeyler, ama 1 baytlık yerel kodlama (yapmak için zar zor aklı başında bir şey)olarak kodlama belirtme
    • 370164 sonuçları / sn

Benim en iyi deneyin şu oldu:

    char[] oldChars = new char[s.length()];
    s.getChars(0, s.length(), oldChars, 0);
    char[] newChars = new char[s.length()];
    int newLen = 0;
    for (int j = 0; j < s.length(); j  ) {
        char ch = oldChars[j];
        if (ch >= ' ') {
            newChars[newLen] = ch;
            newLen  ;
        }
    }
    s = new String(newChars, 0, newLen);

Bunu daha hızlı yapmak için nasıl bir fikriniz var mı?

Çok garip bir soru cevapladığınız için Bonus puan: neden "utf-8" karakter doğrudan verimleri kullanarak daha iyi bir performans ön tahsis statik Charset.forName("utf-8") sabit adını kullanarak mı?

Güncelleme

  • Öneriratchet ucubeetkileyici 3105590 sonuçları sn performans, 24% iyileşme / verim!
  • ÖneriEd Staubverimleri henüz başka bir gelişme / sn - 3471017 sonuçları, 12% önceki en iyi üzerinde.

Güncelleme 2

Önerilen çözümlerden ve tüm mutasyonlar çapraz tahsil etmek için elimden geleni yaptım ve small benchmarking framework at github olarak yayımladım. Şu anda 17 algoritmaları spor. Bunlardan biri "" - . özel ^em>Voo1algoritma (provided by SO user Voo) karmaşık yansıma hileler ama JVM dizeleri' devlet, böylece ayrı ayrı karşılaştırılan. bozulur böylece yıldız hız kazandırmak, istihdam

Ve o kutuda sonuçları öğrenin çalıştırmak için rica ederim. İşte benim sahip olduğum sonuçlarının bir özeti. Özellikleri:

  • Sid, Debian
  • 2.6.39-2-amd64 (x86_64) Linux
  • Java* *22, paketi bir JVM yüklü olarak tanımlıyor
    • (TM) SE çalışma Zamanı Ortamı (yapı 1.6.0_24-b07) Java
    • Java Fi(TM) 64-Bit Server VM (19.1-b02, karma mod kurmak)

Farklı algoritmalar giriş verileri farklı bir dizi verilen sonuçta farklı sonuçlar. 3 mod: bir kıyaslama yaptım

Aynı tek bir dize

Bu mod sürekli olarak aynı tek bir dize StringSource sınıfı tarafından sağlanan çalışır. Hesaplaşmaya

 Ops / s  │ Algorithm
──────────┼──────────────────────────────
6 535 947 │ Voo1
──────────┼──────────────────────────────
5 350 454 │ RatchetFreak2EdStaub1GreyCat1
5 249 343 │ EdStaub1
5 002 501 │ EdStaub1GreyCat1
4 859 086 │ ArrayOfCharFromStringCharAt
4 295 532 │ RatchetFreak1
4 045 307 │ ArrayOfCharFromArrayOfChar
2 790 178 │ RatchetFreak2EdStaub1GreyCat2
2 583 311 │ RatchetFreak2
1 274 859 │ StringBuilderChar
1 138 174 │ StringBuilderCodePoint
  994 727 │ ArrayOfByteUTF8String
  918 611 │ ArrayOfByteUTF8Const
  756 086 │ MatcherReplace
  598 945 │ StringReplaceAll
  460 045 │ ArrayOfByteWindows1251

Manyak şeklinde: Same single string chart

Birden çok dize, 100% dizeleri kontrol karakterleri içerir

Kaynak sağlayıcı dize öncesi oluşturulan rasgele dizeleri böylece (0..127) karakter kümesi kullanarak bir sürü neredeyse tüm dizeleri en az bir denetim karakteri içeriyordu. Algoritmalar hepsini öncesi dönemde oluşturulan bu diziden dizeleri moda aldı.

 Ops / s  │ Algorithm
──────────┼──────────────────────────────
2 123 142 │ Voo1
──────────┼──────────────────────────────
1 782 214 │ EdStaub1
1 776 199 │ EdStaub1GreyCat1
1 694 628 │ ArrayOfCharFromStringCharAt
1 481 481 │ ArrayOfCharFromArrayOfChar
1 460 067 │ RatchetFreak2EdStaub1GreyCat1
1 438 435 │ RatchetFreak2EdStaub1GreyCat2
1 366 494 │ RatchetFreak2
1 349 710 │ RatchetFreak1
  893 176 │ ArrayOfByteUTF8String
  817 127 │ ArrayOfByteUTF8Const
  778 089 │ StringBuilderChar
  734 754 │ StringBuilderCodePoint
  377 829 │ ArrayOfByteWindows1251
  224 140 │ MatcherReplace
  211 104 │ StringReplaceAll

Manyak şeklinde: Multiple strings, 100% concentration

Birden çok dize, 1% dizeleri kontrol karakterleri içerir

Önceki gibi, ama sadece %1'i dizeleri idi oluşturulan kontrol karakterleri - diğer 99% oluşturulan kullanarak [32..127] karakter kümesi, yani edemediler içeren kontrol karakterleri. Bu sentetik yük gerçek dünyaya en yakın benim evimde bu algoritma uygulaması geliyor.

 Ops / s  │ Algorithm
──────────┼──────────────────────────────
3 711 952 │ Voo1
──────────┼──────────────────────────────
2 851 440 │ EdStaub1GreyCat1
2 455 796 │ EdStaub1
2 426 007 │ ArrayOfCharFromStringCharAt
2 347 969 │ RatchetFreak2EdStaub1GreyCat2
2 242 152 │ RatchetFreak1
2 171 553 │ ArrayOfCharFromArrayOfChar
1 922 707 │ RatchetFreak2EdStaub1GreyCat1
1 857 010 │ RatchetFreak2
1 023 751 │ ArrayOfByteUTF8String
  939 055 │ StringBuilderChar
  907 194 │ ArrayOfByteUTF8Const
  841 963 │ StringBuilderCodePoint
  606 465 │ MatcherReplace
  501 555 │ StringReplaceAll
  381 185 │ ArrayOfByteWindows1251

Manyak şeklinde: Multiple strings, 1% concentration

Çok zor benim için kim karar verilen en iyi cevap, ama belirli bir gerçek dünya uygulama için en iyi çözüm olduğuna bakınca,/ilham Ed Staub, sanırım olur adil mark onun cevabı. Bu yer, giriş götüren her şey için teşekkürler çok yararlı ve değerli oldu. Kutusu üzerinde test paketi çalıştırmak için çekinmeyin ve daha iyi çözümler önermek (çalışma JNI çözümü olan var mı?).

Referanslar

CEVAP
23 AĞUSTOS 2011, Salı


1 char dizi kullanarak biraz daha iyi sonuç verebilir

int length = s.length();
char[] oldChars = new char[length];
s.getChars(0, length, oldChars, 0);
int newLen = 0;
for (int j = 0; j < length; j  ) {
    char ch = oldChars[j];
    if (ch >= ' ') {
        oldChars[newLen] = ch;
        newLen  ;
    }
}
s = new String(oldChars, 0, newLen);

ve s.length(); çağrılar kaçındım

bu işe yarayabilir mikro-optimizasyon başka bir şeydir

int length = s.length();
char[] oldChars = new char[length 1];
s.getChars(0, length, oldChars, 0);
oldChars[length]='\0';//avoiding explicit bound check in while
int newLen=-1;
while(oldChars[  newLen]>=' ');//find first non-printable,
                       // if there are none it ends on the null char I appended
for (int  j = newLen; j < length; j  ) {
    char ch = oldChars[j];
    if (ch >= ' ') {
        oldChars[newLen] = ch;//the while avoids repeated overwriting here when newLen==j
        newLen  ;
    }
}
s = new String(oldChars, 0, newLen);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Mark Hyder

    Mark Hyder

    6 EKİM 2011
  • Rickymon Tero

    Rickymon Ter

    1 Ocak 2007
  • UniqueApps

    UniqueApps

    4 Ocak 2009