title: Why is MultiFieldQueryParser so much slower than creating query by hand?
body: <p>I am using Lucene.net to index a product catalog.  I was profiling my searches using ANTS Profiler and I noticed that the act of creating and parsing a query using the MultiFieldQueryParser took nearly as long as the actual search (approx 100ms).  I then tried creating the query manually, which happens very fast (approx 1ms).  I would rather not have to parse manually, although it does give me the same result set, I fear I might not be handling certain use cases or inputs (although the input is coming from a text search on a website and the users will no know anything about Lucene's search syntax).  My code (with both methods) is as follows:</p>
  
  <pre><code>        IApplicationSettings settings = new ApplicationSettingService();
          FSDirectory directory = FSDirectory.Open(new DirectoryInfo(settings.GetSetting&lt;string&gt;("LuceneMainSearchDirectory")));
          RAMDirectory ramDir = new RAMDirectory(directory);
          _Searcher = new IndexSearcher(ramDir, true);        
          string[] searchFields = new string[] { "ProductName", "ProductLongDescription", "BrandName", "CategoryName" };
  
          //Add a wildcard character to end of search to give broader results 
          if (!searchTerm.EndsWith(" ")) { searchTerm = searchTerm + "*"; }
  
  
          //Use query parser...this  block typically takes about 100ms on my machine, roughly 40% on the constructor and 60% on the call to Parse
          MultiFieldQueryParser multiParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchFields, _analyzer);
          multiParser.SetDefaultOperator(QueryParser.AND_OPERATOR);
          Query query = multiParser.Parse(searchTerm);
  
  
  
          //Manually create query....this block doesn't even take 1ms on my machine
          BooleanQuery booleanQuery = new BooleanQuery(true);
          var terms = searchTerm.Split(' ');
          foreach (string s in terms)
          {
              BooleanQuery subQuery = new BooleanQuery(true);
              if (!s.EndsWith("*"))
              {
                  Query query1 = new TermQuery(new Term("ProductName", s));
                  Query query2 = new TermQuery(new Term("ProductLongDescription", s));
                  Query query3 = new TermQuery(new Term("BrandName", s));
                  Query query4 = new TermQuery(new Term("CategoryName", s));
                  subQuery.Add(query1, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query2, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query3, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query4, BooleanClause.Occur.SHOULD);
              }
              else
              {
                  Query query1 = new WildcardQuery(new Term("ProductName", s));
                  Query query2 = new WildcardQuery(new Term("ProductLongDescription", s));
                  Query query3 = new WildcardQuery(new Term("BrandName", s));
                  Query query4 = new WildcardQuery(new Term("CategoryName", s));
                  subQuery.Add(query1, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query2, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query3, BooleanClause.Occur.SHOULD);
                  subQuery.Add(query4, BooleanClause.Occur.SHOULD);
              }
              booleanQuery.Add(subQuery, BooleanClause.Occur.MUST);
          }
  
  
      //Run the search....results are the same for simple multiword text queries
          var result2 = _Searcher.Search(booleanQuery, null, maxResults);
          var result = _Searcher.Search(query, null, maxResults);
  </code></pre>
  
  <p>One option to save me using the manual query build might be to share the MultiFieldQueryParser, but I gather its Parse method is not threadsafe (although I only read that in relation to the java version...please correct me if I am wrong in that assumption).</p>
  
  <p>Am I doing something wrong or is this just the nature of the beast?</p>