簡體   English   中英

如何在不使用Java創建對象的情況下匹配正則表達式?

[英]How to match regular expression without creating objects in Java?

我正在研究reg表達式匹配功能。 問題是,該函數將由嵌套循環內的框架調用。 如果創建了臨時對象,GC將導致很大的性能問題。

是否可以在不創建臨時對象(Pattern,Matcher)的情況下處理正則表達式? 重寫regexp類是我的最后選擇。

最好的選擇是在問題出現時及時處理-可能不會。 大約10年前,圍繞GC處理大量小型活動對象的性能問題是一個問題,但現在已經非常出色了。

如果確實需要優化,則應采用更改GC選項的形式-例如,年輕一代的大小,而不要嘗試在代碼中進行優化。

Matcher對象不是線程安全的,因此除非調用reset()方法(在單個線程中應該可以正常工作),否則您將無法重用它們-請參見Java Regex線程安全嗎?

引用一句老話:

使它起作用,使其正確,使其快速。 (以該順序)

因此,在執行任何繁瑣的優化步驟之前,只需編寫初始的,簡單易用的適當代碼(在這種情況下,如果可能的話,將涉及預編譯模式)。 運行一些測試,看看性能是否不足,然后優化正則表達式部分是否成為瓶頸。

如果對象的創建(和清除)是一個嚴重的瓶頸(與實際的正則表達式本身相比),那么您可能需要實現使用對象池的自己的解決方案(因此不創建對象,只需從對象中重置並重新使用)池)。 我懷疑這是否會導致任何嚴重的性能提升,因此您應該首先進行基准測試,以查看甚至有多少增益(如果將對象創建/清理性能提高50%,是否值得?)。

這聽起來像過早的優化。

編寫最簡單的代碼,然后在實際設置中對其進行分析,並查看性能或內存分配模式是否存在問題。 如果有,請解決您發現的特定問題。

現代JVM非常擅長於垃圾收集短期對象。

您可以預編譯正則表達式,如果您多次重復使用同一個正則表達式,則很有用。

代替

boolean foundMatch = subjectString.matches("a.*b");

(無論如何都會創建一個臨時的已編譯Pattern ),您可以使用

Pattern regex = Pattern.compile("a.*b");
// loop here
// do something...
    Matcher regexMatcher = regex.matcher(subjectString);
    boolean foundMatch = regexMatcher.matches()
// loop end

不過,很難說是否會有任何相關的性能優勢。

似乎您正在進行早期優化,對您而言,這很可能是無用的。 您如何進行測試並做出決定?

歡呼,尤金

我認為它有2種可行的選擇:

  1. 通過查看源代碼PatternMatcher來編寫自己的用於匹配正則表達式的邏輯。
  2. 在處理完這些對象后,可以通過運行它們相應的finalize()函數來顯式初始化這些對象的集合,而不是等待GC運行它。

利弊

  1. 將來需要測試和維護許多工作,但是您可以完全控制要執行的操作。

  2. 不建議干擾GC的運行,干凈的解決方案和簡單的解決方案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM