-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add fast path for ASCII case folding
One of our production services uses re2j to match several hundred mostly case-insensitive patterns of varying complexity against text. We observed that approximately 12% of CPU time was being spent in toLowerCase() as called from simpleFold(), due to the necessity of doing at least one character data lookup per Inst.Rune in the common case that the input rune being examined did not match the instruction. As a fix, implement a method equalsIgnoreCase() that performs Unicode-aware case-insensitive comparison between two runes, with a fast path for the common case where both input runes are ASCII, and use it in Inst for single-rune case-insensitive comparison. This takes character data lookups out of the hot path. The existing re2j benchmarks did not exercise case-insensitive patterns, so add a new benchmark that executes a mostly ASCII regex pattern on a text containing a mix of ASCII and Unicode characters (generated using a Hungarian "lorem ipsum" text generator). Also add unit tests for the new equality comparison logic. Signed-off-by: Máté Szabó <[email protected]>
- Loading branch information
1 parent
3e685d9
commit dc7d6e5
Showing
8 changed files
with
306 additions
and
34 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
benchmarks/src/main/java/com/google/re2j/benchmark/BenchmarkCaseInsensitiveSubmatch.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2022 The Go Authors. All rights reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style | ||
* license that can be found in the LICENSE file. | ||
*/ | ||
package com.google.re2j.benchmark; | ||
|
||
import org.openjdk.jmh.annotations.*; | ||
import org.openjdk.jmh.infra.Blackhole; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
// BenchmarkCaseInsensitiveSubmatch tests the performance of case-insensitive matching | ||
// by testing a mostly ASCII regex pattern versus a moderately large text containing both | ||
// ASCII and Unicode characters. | ||
@OutputTimeUnit(TimeUnit.MICROSECONDS) | ||
@State(Scope.Benchmark) | ||
public class BenchmarkCaseInsensitiveSubmatch { | ||
@Param({"JDK", "RE2J"}) | ||
private Implementations impl; | ||
|
||
@Param({"true", "false"}) | ||
private boolean binary; | ||
|
||
private final byte[] bytes = BenchmarkUtils.readResourceFile("unicode-sample-text.txt"); | ||
|
||
private final String text = new String(bytes, StandardCharsets.UTF_8); | ||
|
||
private Implementations.Pattern pattern; | ||
|
||
@Setup | ||
public void setup() { | ||
pattern = | ||
Implementations.Pattern.compile( | ||
impl, | ||
"(prepaid|my)(estub|htspace|mercy|nstrom|paycard|milestonecard|bpcreditcard|groundbiz|giftcardsite|pascoconnect|loweslife|balancenow|aarpmedicare|ccpay|cardstatement|cardstatus)\\.[a-z]{2,6}", | ||
Implementations.Pattern.FLAG_CASE_INSENSITIVE); | ||
} | ||
|
||
@Benchmark | ||
public void caseInsensitiveSubMatch(Blackhole bh) { | ||
Implementations.Matcher matcher = binary ? pattern.matcher(bytes) : pattern.matcher(text); | ||
int count = 0; | ||
while (matcher.find()) { | ||
bh.consume(matcher.group()); | ||
count++; | ||
} | ||
if (count != 0) { | ||
throw new AssertionError("Expected to not match anything"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
benchmarks/src/main/java/com/google/re2j/benchmark/BenchmarkUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright (c) 2022 The Go Authors. All rights reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style | ||
* license that can be found in the LICENSE file. | ||
*/ | ||
package com.google.re2j.benchmark; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
public class BenchmarkUtils { | ||
|
||
// readResourceFile reads the contents of the Java resource file at the given path. | ||
public static byte[] readResourceFile(String name) { | ||
try (InputStream in = BenchmarkUtils.class.getClassLoader().getResourceAsStream(name); | ||
ByteArrayOutputStream out = new ByteArrayOutputStream()) { | ||
int read; | ||
while ((read = in.read()) > -1) { | ||
out.write(read); | ||
} | ||
return out.toByteArray(); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private BenchmarkUtils() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
Lórum ipse talán a körös, völő a legkevésbé aggodalkan. A szülényöt nem lehet kantnia, de meg lehet büdösödnie, tramót | ||
hevnie. Az egyik, hogy áptin fagyvához szélyeznie kell a struccot a szövedetséghez. A fagyva táns időközönként szemegi | ||
azokat a vinákat, akik nem pedzkezéltek hozzá a falásokhoz. Ez általában a neter külésén zagaznan, de nem minden tányságban). | ||
Az élhely helyesen kaponálog meg, ha talmasos ódogály van beállítva (klán a „kapé +1” bosztaganba szalkol). Ezt a fárát | ||
csak kord vinák talmazhatják fajtásba. Ha biztosan a talmasos ódogály van beállítva, akkor feltehetőleg azért nem gyentes, | ||
mivel reszet lehet a harás dián. | ||
|
||
A szeleteken feli hullásokat azonban csependeznie kell, és nem zátkacs kezések dalan piszteteinek kőzésére hajganyoznia. | ||
Konlat szemés matódágot sóvadt ütődésök (busztikus és jedés ütődésök, fűző fogtat) haságában az egység kezésben fojtott | ||
szülésök vezők. Álám csalan vélvetek hiányában a külön lemérben egyén üdöngő reszletelés alapján. - a jelen polódás sofőn | ||
teli funciája szerint, amennyiben a latika vagy latikák nem gurítnak az itató istában, vagy gurítnak ugyan, de ott nincs | ||
hozzájuk rendelve sujas szalovagyás. Slem ha vannak csalan vélvetek, akkor a vira kezésben fojtott szülésök alapján, | ||
kivéve a vira konlat kezésben egyén busztikus, jedés, és fűző fogyást mazsánc ütődésöket, amelyeket a sofőn teli funcia | ||
„mető” karhelében egyén üdöngő reszleteléssel kell hebédnie. Amennyiben a fogás kezések, csalan vélvetek alapján bokrol, | ||
a csalan vélveteknek felinek kell lenniük szeletre is, azaz a meteleteknek udott módon fregzálniuk kell a szeletekre | ||
ciszti márkoldozásokat. A kanzásra szeres latikák és akangálok kart nyugos fogtatának emtője türkmés egy, a leviszok | ||
zokmás pasztránát lehetővé szikér reszleteléssel, vagy a kényszerű glág pipényesével [golygó (szocdes) glág fabag]. | ||
|
||
Lórum ipse számos máshol nehezen szülős bérzetet és akásos nészest is gőzik. A jénzés az oforsás szerikése, amely a nyiros | ||
cigorúságot marc érdelődi. - folyos helles kelídségként ez datásban mintegy neményező hárlanságot kokszoltak fel, ami a | ||
rományos datás hitatos csípő jénzéstől több, mint funsz gyalmatlan kadonossal dugol el. A folyos kelídségekből a kedésben | ||
halmas kadonos, ami még őrző tőcében a sali puffadt feles gaság által paradás csípőkből fodonított, nem érte el a cutbamás | ||
hárlanságot. Ebből a ságavas kelídség prázs hárlanságot parsápogt ki, a telő kelídség pedig gyesedte a hígság hárlanságot. | ||
A költség datást pirág levica még kült volt, hiszen az ez puffadt kelídségről a topis és izzadt kedet áriusa kedés első | ||
sebérőiben tetlegt meg. Így hetsze a toron ranyos jénzés őrző cserese, hiszen az árius hengje több göngyet esetén foszlékony | ||
hatlan, tehát a kelídséget prés falmatától lehet szennyeznie. Vadmányság a datás első senyvben függönyös szengeségként | ||
halmas spol hárlanság a szata gyalmatlan tízel oforsás csillatát parsápogta ki. | ||
|
||
Szális érítmény, hogyan fognak kaporoznia zavadékony ortoroh, ha nem lesz tank. A manítáp sokkal tovább vásodik majd, | ||
mint a vánság halcán hatlan, de a manítáp nem kívós hullák dicsőültjének. Ez a tedalhanya szorosan szakodik a ségi bokarás | ||
lombácsához. A köző dicsőültök hákár lakoltja zsint fóka 0-3000-ig. A tank és a dózsa a heli nagramának egy oszlokáig | ||
menekelkedik. Szöszkes görzenlelése karágos, hogy a köző hozatok, az öngő, a konsátány és a tank ináda a tető salata iség | ||
szampós néződését tögeskezi. Ez a dózsa úgy ábol a mezőben, mint a heredás izzása, borsalja a fogatot, de nalanja a | ||
sültök által nácstagos talan iséget. | ||
|
||
A sulás banúval pakarál, házásai batányos pariszt ségzőből pakarálnak, kacér házása a tonccal szalminális, fedése táns | ||
fajogány, a kukók fatlan kező ámos formányos - válkatos sembecserejek. A tösdön, a szildás fónin egy zátott gyülég, ill. | ||
egy zátott ruzgomatás, míg a szakony fónin latózok tékednek esztözre. A számortó stehésen 48-100 m2 pintohos jális gyülégök | ||
staságára van páns. A filevés folyása a szeges gyülégökhöz rendelve tékedik esztözre, így ezek a gyülégök kajósak. | ||
A törömnyi gyülég, latóz, jedés törmendésének hábája a brómok szerint vízlik: A gráta során bizony elég sok környe | ||
ügyködt, amelynek egy varását utólag el lehetett sodnia, más varása gyezőnek vitelt. Az éredő nem fúlódt tatlannak, | ||
bár a tendó ínyes csiszésekben nem elég fokos lévén, kötérbe se nyilajtott a saját satott gráta. | ||
|
||
Tizmus a pacozások odásánál ösztésben pombiskálnak a kürtők és kernák vaglárájával kulla sodúk. Fegyítés a dária száromozása | ||
a kohé bókásos lyukáinak polos száromozása is lehet. Kezés a hozás művelt nyúlt, csites legyen ; porcsata ne lalmazjon | ||
túl friss szortéros, fojtos, illetve ketes tödőket. A folyék cserkéjét, a sodú melgőjét és fenyőjét az alamok szabadon | ||
vilizálhatják meg. Tagság herő: dévatás pacozás: 180 teli, monság pacozás: 110 teli, bota pacozás: 60 teli. A neslés | ||
egész fonílásán éresítő trigy keredő lendikes zetíl (folány cocilkozás fogás törzs rimázat páter falás böjtő mit léka | ||
fogás kérde), melynek nyúlása a lendikes juhuzmusok és vihos tördője, matált kalomot silkodál a bükkös skum számítárára. | ||
Szulyái lopszli és himő zális bűnök hatódtak fel a lipés prodása címlés kohéján, a fatos zsürtegek alapján: | ||
|
||
Mintegy 1000 ha varlánz nyonkája a fogtatlan, és doncsok tíz hódik jáltos varlánz csajbánya a sosos hajda a suvatok fájékos | ||
mahostarára. Ezt csatizással, a balan mutához hasonlóan, a nírtek esztekes ítékének (pityi) fűzesében títos kétezdeznie. | ||
A szike közösen volna títos urálnia azoknak a viergéseknek, akik nem valiskoznak ezes suvattal, és azoknak, akiknek van | ||
köszkes csúságuk. Ezeket a csúságokat hagyakodhatnák a pityibe, amíg a csúsággal nem bűnösek többé-kevésbé a fecselő cinget | ||
„haljadnák” a repern ítékbe. Títos lenne varannia a mekvény más szélyiségeinek is ezen suvatokban való kosztát. Ez a | ||
fűzes egyes plékben sérő a szeresti fariásban. Elsősorban a csávas viergéseket kodná azáltal, hogy nem volna esztekes | ||
szára számukra, amikor közvetlenül csens után igen fáns, tomorcos fendőn kell mozdeztetniük a varlánzukat. | ||
|
||
A nalással és fenestikkel, csürgényökkel, menségekkel és pedéssel fikarok turvajkok is a szolvas fara sovácsait filtezik | ||
maság elé. A trony pantás elsősorban a randékok hajtáján tiska baksias hígságokkal tivódoz. A kélenemény maságait hetes, | ||
szolvas, páragos besztként szabványítja meg a peség minden hajtáján. A dalkármány folt sedicse (koncák, pacsos pajlág, | ||
termőr és fehes karság) hatos hesemben is lizoláz a sajlékony kedéseknek. A kezős paporásoknál a dura miatt +3 járót | ||
kell üzesereznie. Venc tekerenek: parkingban és göntésben: ravara ; feheregésben és lenemetben: redség. Folya tekeren: | ||
a palatás gyezőhöz: letlem, a második gyezőhöz: zombon. | ||
|
||
A „szepokra” arma egyike azoknak, amelyek rengeteg szíjas andoknak és aktának kednek menicsora. Ahogy a baga fina is több | ||
mint húsz armát rodik a „hó” vítésére, a „szepokra” dingólyája is számtalan ingebentent vicskohat. Hódhatik például fontúrt, | ||
visztet, irátot, cicibizmust, a dohajtolás előkedét, s a hariát lehetne még passzolnia. „Nincs olyan, hogy egy várlóval | ||
ne sondítna valamiféle hamlomós balova is. A lizajzált smény ügezek általában egy (vagy több) olyan bajkozás, akta vagy | ||
lojt emény őrlését hódják, amelyek valamilyen bilománynál fogva nem szárznak meg a dulláknak. A szalan bátkas szulások | ||
felől nézve a lizajzál gyakran hódja a hugyos sejtesek és varcárok pális figyelem szinomát is. A lizajzál patlabora a | ||
lizmus törös lizajzálának is olatot, zákult szfilvet téveng. | ||
|
||
Molás a fárd alkep gurnájára kedelt tikuflus és tonkolt derej körmet. A meret pest füle talant varcokságában a tödés nem | ||
a nyolc érdeges morgos mihanás folójával, hanem a tizedik mihanás folójakor szemző tigével molkodik le. A hozott köztes | ||
folád varcokságában azonban - az árzatos bájos mafrucákhoz buzatos netogok átlagosan 15 sutója számára csesti szigást | ||
igatos cseredres zsingenségektől eltekintve - a hozott halkolások az érdeges hadék végén szélyellnek. Ez azt kuskolja, | ||
hogy a netogok zetőr bizmusa lasztérzó hozott halkolásban méredik vizsmát. Pontosabban a kilencedik és a tizedik mihanásban | ||
nem mérednek vizsmát olyan halkolásban, amely birázja őket arra, hogy hozott ártáson lődjék le a tigét. Éppen az ártás az, | ||
ami miatt a hozott köztes lönövéjéből a rátos varcokság jelenleg nem szelső, márpedig a rátos varcokság tagálását tekintve | ||
az ábítás nyagvató idségei vizetik módnia az alom és az ehhez képest ébrengő füle talant tamangásokból emező farlókat. | ||
Az eges ványos tödés más varányból, de szintén tatók papija lehet a malan netogok számára is. | ||
|
||
Viszont az egész szájék fürgőjét reteli katatos sörös szobzó neméréből már évenes bizárlát kell láznia és gyújtnia kell | ||
ellene. Szóval a lehető évenes dugság arról szadoznia, hogy minden atyus evező külésökkel buzonál. Ez már csak azért is | ||
dugság, mert ha nem szántna az állott szinó, akkor sem buzonálna minden atyus evező külésökkel. A szordiumban és | ||
tulajdonképpen az imányban, mindig az nyúlékosnak vannak külései. Egyébként ez is az állott szinó lanságát kodja. A másik | ||
ami szintén tagadhatatlan, hogy a gyulucs összehasonlíthatatlanul többet kundozik bármely mezgő csokriumánál. A raca a | ||
bértő a hajtin érzéséből. | ||
|
||
Rémes buzódást raccsol: „Egy basé az árlók, két basé az adások és ártályok, egy, vagy két basé a gomászok számára”. | ||
A gomász fukalai talányosak és világosan szélyeznek a szalkutyával és a tenélennel. Az észer gyatás maság nem lehet | ||
kevésbé hatlan a holás és selég regeztetében, mint a salan habitások: a meszmerek, amiket a mezerek hangjában előre kednek, | ||
gyorsan kettősek, ha titos jövék szüregetnek fel. Végül, az észer gyatás maság háromtól öt rincig tung béresben kítos, | ||
és meg is kell csepítnie, ellentétben azokkal a nem busztos szaftos elkesekkel, amelyek az adék makáját gyakran szegetik. | ||
Ha bárki úgy csalmasztná nincs tobajban, nem adathatja őrizetlenül a vistalkáját, nem szalhatja le a hinatát avval a | ||
biztos csonyával, hogy ott lesz amikor hatozik. A barák valahogy mindig is csempekeztek szaldagra és a költésökre. | ||
A hűsítő, hidekes, szort és feli költésökre is. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.