Бүх хэвлэгддэггүй тэмдэгтүүдийг мөрөөс хуулах хамгийн хурдан арга нь юу вэ?
Java дээр үү?
Одоогоор би 138 байт, 131 тэмдэгт мөрийг туршиж, хэмжиж үзлээ:
replaceAll ()
- хамгийн удаан арга
replaceAll ()
codepointAt ()
-г ашиглан кодын цэгүүдийг авч, StringBuffer дээр нэмэх
charAt ()
-г ашиглан тэмдэгт авч, StringBuffer дээр хавсаргана уу.
char []
буферийг урьдчилан хуваарилж, charAt ()
-г ашиглан тэмдэгтүүдийг авч, энэ буферийг дүүргээд дараа нь String рүү хөрвүүл.
char []
буферийг урьдчилан хуваарилах, одоо байгаа String-ийн бүх тэмдэгтүүдийг getChars ()
ашиглан нэг дор авах, хуучин буфер дээр давтах. нэг нэгээр нь нэмж шинэ буферийг дүүргээд дараа нь шинэ буферийг String болгон хөрвүүлнэ - миний хамгийн хурдан хувилбар
байт []
], getBytes ()
ба кодчиллыг "utf-8" гэж зааж өгөх
байт []
буфертай ижил зүйл, гэхдээ кодчиллыг тогтмол гэж зааж өгсөн Charset.forName ("utf-8")
байт []
буфертай ижил зүйл, гэхдээ кодчиллыг 1 байт локал кодчилол гэж зааж өгөх (бараг л эрүүл ухаантай зүйл хийх)
Миний хамгийн сайн хичээсэн зүйл бол дараахь зүйл байв:
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")
?
I Санал болгож буй бүх шийдлүүд болон тэдгээрийн хөндлөн мутацийг цуглуулж, github дээр жижиг жишиг тогтолцоо болгон хэвлүүлэхийн тулд би чадах бүхнээ хийсэн. Одоогийн байдлаар 17 алгоритмаар ажилладаг. Тэдгээрийн нэг нь "тусгай" - Voo1 алгоритм ( SO хэрэглэгчийн өгсөн Voo ) нь нарийн тусгалын заль мэхийг ашигладаг тул оддын хурдыг олж авдаг боловч JVM мөрүүдийн төлөв байдлыг алдагдуулдаг тул жишиг болж өгдөг. тусад нь.
Та үүнийг шалгаж, хайрцган дээрээ үр дүнг тодорхойлохын тулд ажиллуулаарай. Миний олж авсан үр дүнгийн тойм энд байна. Энэ нь:
sun-java6-jdk-6.24-1
багцаас суулгасан, JVM нь өөрийгөө
Янз бүрийн алгоритмууд эцэст нь өөр өөр үр дүнг харуулдаг оролтын өгөгдлийн өөр багц. Би 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
График хэлбэрээр:
(эх сурвалж: greycat.ru )
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
Бүртгэгдсэн хэлбэрээр:
(эх сурвалж: greycat.ru )
Өмнөхтэй адил боловч мөрийн зөвхөн 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
Бүртгэгдсэн хэлбэрээр:
(эх сурвалж: greycat.ru )
Хэн хамгийн сайн хариултыг өгөхийг шийдэх нь надад маш хэцүү байдаг боловч бодит хэрэглээнд өгөгдсөн хамгийн сайн шийдлийг Эд Стаубаас санаа авч, Түүний хариултыг тэмдэглэх нь шударга байх болов уу. Үүнд оролцсон бүх хүмүүст баярлалаа, таны оруулсан санал маш их тус болж, үнэлж баршгүй зүйл болсон. Хайрцаг дээрээ туршилтын багцыг ажиллуулж, үүнээс ч илүү сайн шийдлүүдийг санал болгож болно (JNI шийдэл ажиллаж байна уу, хэн нэгэн үү?).