Java String-ээс бүх хэвлэгдэхгүй тэмдэгтүүдийг хуулах хамгийн хурдан арга

Бүх хэвлэгддэггүй тэмдэгтүүдийг мөрөөс хуулах хамгийн хурдан арга нь юу вэ? Java дээр үү?

Одоогоор би 138 байт, 131 тэмдэгт мөрийг туршиж, хэмжиж үзлээ:

  • String's replaceAll () - хамгийн удаан арга
    • 517009 үр дүн / сек
  • Хээ загварыг урьдчилан эмхэтгээд дараа нь Matcher-ийн replaceAll ()
    • 637836 үр дүн / сек
  • StringBuffer-ийг ашиглаад codepointAt () -г ашиглан кодын цэгүүдийг авч, StringBuffer дээр нэмэх
    • 711946 үр дүн / сек
  • StringBuffer-ийг ашиглаад charAt () -г ашиглан тэмдэгт авч, StringBuffer дээр хавсаргана уу.
    • 1052964 үр дүн / сек
  • a char [] буферийг урьдчилан хуваарилж, charAt () -г ашиглан тэмдэгтүүдийг авч, энэ буферийг дүүргээд дараа нь String рүү хөрвүүл.
    • 2022653 үр дүн / сек
  • 2 char [] буферийг урьдчилан хуваарилах, одоо байгаа String-ийн бүх тэмдэгтүүдийг getChars () ашиглан нэг дор авах, хуучин буфер дээр давтах. нэг нэгээр нь нэмж шинэ буферийг дүүргээд дараа нь шинэ буферийг String болгон хөрвүүлнэ - миний хамгийн хурдан хувилбар
    • 2502502 үр дүн / сек
  • 2 буфертай ижил зүйлс - зөвхөн байт [] ], getBytes () ба кодчиллыг "utf-8" гэж зааж өгөх
    • 857485 үр дүн / сек
  • 2 байт [] буфертай ижил зүйл, гэхдээ кодчиллыг тогтмол гэж зааж өгсөн Charset.forName ("utf-8")
    • 791076 үр дүн / сек
  • 2 байт [] буфертай ижил зүйл, гэхдээ кодчиллыг 1 байт локал кодчилол гэж зааж өгөх (бараг л эрүүл ухаантай зүйл хийх)
    • 370164 үр дүн / сек

Миний хамгийн сайн хичээсэн зүйл бол дараахь зүйл байв:

    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);

Үүнийг хэрхэн хурдан болгох талаар ямар нэгэн бодол байна уу?

Маш хачин асуултанд хариулсан шагналын оноо: яагаад "utf-8" charset-ийг ашигласан бэ? нэр нь урьдчилан хуваарилагдсан статик const ашиглахаас шууд илүү сайн гүйцэтгэл өгдөг Charset.forName ("utf-8") ?

Шинэчлэлт

  • ратчетийн гажиг -с санал болгосноор гайхалтай 3105590 үр дүн гарч байна. / сек гүйцэтгэл, + 24% сайжруулалт!
  • Эд Стаубаас санал болгосноор дахин нэг сайжруулалт гарч ирэв - 3471017 үр дүн / сек, өмнөх хамгийн сайн үзүүлэлтээс + 12%.

Шинэчлэлт 2

I Санал болгож буй бүх шийдлүүд болон тэдгээрийн хөндлөн мутацийг цуглуулж, github дээр жижиг жишиг тогтолцоо болгон хэвлүүлэхийн тулд би чадах бүхнээ хийсэн. Одоогийн байдлаар 17 алгоритмаар ажилладаг. Тэдгээрийн нэг нь "тусгай" - Voo1 алгоритм ( SO хэрэглэгчийн өгсөн Voo ) нь нарийн тусгалын заль мэхийг ашигладаг тул оддын хурдыг олж авдаг боловч JVM мөрүүдийн төлөв байдлыг алдагдуулдаг тул жишиг болж өгдөг. тусад нь.

Та үүнийг шалгаж, хайрцган дээрээ үр дүнг тодорхойлохын тулд ажиллуулаарай. Миний олж авсан үр дүнгийн тойм энд байна. Энэ нь:

  • Debian sid
  • Linux 2.6.39-2-amd64 (x86_64)
  • Java sun-java6-jdk-6.24-1 багцаас суулгасан, JVM нь өөрийгөө
    • Java (TM) SE Runtime Environment (build 1.6.0_24-b07)
    • Java HotSpot (TM) 64-bit Server VM (build 19.1-b02, холимог горим)

Янз бүрийн алгоритмууд эцэст нь өөр өөр үр дүнг харуулдаг оролтын өгөгдлийн өөр багц. Би 3 горимд жишиг ажиллуулж үзсэн:

Ижил дан мөр

Энэ горим нь тогтмол байдлаар StringSource ангиас өгсөн ижил мөр дээр ажилладаг. Showdown нь:

 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

График хэлбэрээр: Same single string chart
(эх сурвалж: greycat.ru )

Олон тэмдэгт мөрүүд, 100% мөрүүд нь хяналтын тэмдэгтүүд агуулдаг

Source string үзүүлэгч (0..127) тэмдэгт ашиглан олон тооны санамсаргүй мөрүүдийг урьдчилан бүтээсэн. багц - ингэснээр бараг бүх мөрөнд дор хаяж нэг хяналтын тэмдэгт багтсан болно. Алгоритмууд нь урьдчилж бүтээсэн энэхүү массиваас тэмдэгт мөрүүдийг тойрог хэлбэрээр хүлээн авсан.

 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

Бүртгэгдсэн хэлбэрээр: Multiple strings, 100% concentration
(эх сурвалж: greycat.ru )

Олон мөр, мөрний 1% нь хяналтын тэмдэгт агуулдаг

Өмнөхтэй адил боловч мөрийн зөвхөн 1% -ийг хяналтын тэмдэгтээр бүтээсэн - бусад 99 % нь [32..127] тэмдэгт багцыг ашиглахад үүссэн тул тэдгээр нь хяналтын тэмдэгтүүдийг огт агуулж чадахгүй байв. Энэхүү синтетик ачаалал нь миний хувьд энэ алгоритмын бодит хэрэглээнд хамгийн ойр байдаг.

 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

Бүртгэгдсэн хэлбэрээр: Multiple strings, 1% concentration
(эх сурвалж: greycat.ru )

Хэн хамгийн сайн хариултыг өгөхийг шийдэх нь надад маш хэцүү байдаг боловч бодит хэрэглээнд өгөгдсөн хамгийн сайн шийдлийг Эд Стаубаас санаа авч, Түүний хариултыг тэмдэглэх нь шударга байх болов уу. Үүнд оролцсон бүх хүмүүст баярлалаа, таны оруулсан санал маш их тус болж, үнэлж баршгүй зүйл болсон. Хайрцаг дээрээ туршилтын багцыг ажиллуулж, үүнээс ч илүү сайн шийдлүүдийг санал болгож болно (JNI шийдэл ажиллаж байна уу, хэн нэгэн үү?).

Ашигласан материал

80
задан Glorfindel 12 August 2019 в 13:30
поделиться