Issue #3681
Use LinkedHashMap<List<Pair>> Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
2831bfb159
commit
1458854d24
|
@ -61,6 +61,11 @@ public class HttpFields implements Iterable<HttpField>
|
|||
private HttpField[] _fields;
|
||||
private int _size;
|
||||
|
||||
|
||||
private int iterations = 0;
|
||||
private int lookups;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize an empty HttpFields.
|
||||
*/
|
||||
|
@ -98,17 +103,20 @@ public class HttpFields implements Iterable<HttpField>
|
|||
@Override
|
||||
public Iterator<HttpField> iterator()
|
||||
{
|
||||
iterations++;
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
public ListIterator<HttpField> listIterator()
|
||||
{
|
||||
iterations++;
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
|
||||
public Stream<HttpField> stream()
|
||||
{
|
||||
iterations++;
|
||||
return StreamSupport.stream(Arrays.spliterator(_fields,0,_size),false);
|
||||
}
|
||||
|
||||
|
@ -151,6 +159,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public HttpField getField(HttpHeader header)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -162,6 +171,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public HttpField getField(String name)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -173,6 +183,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(HttpField field)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=_size;i-->0;)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -184,6 +195,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(HttpHeader header, String value)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=_size;i-->0;)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -195,6 +207,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(String name, String value)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=_size;i-->0;)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -206,6 +219,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean contains(HttpHeader header)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=_size;i-->0;)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -217,6 +231,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public boolean containsKey(String name)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=_size;i-->0;)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -234,6 +249,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public String get(HttpHeader header)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -251,6 +267,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public String get(String header)
|
||||
{
|
||||
lookups++;
|
||||
for (int i=0;i<_size;i++)
|
||||
{
|
||||
HttpField f=_fields[i];
|
||||
|
@ -268,6 +285,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public List<String> getValuesList(HttpHeader header)
|
||||
{
|
||||
lookups++;
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (HttpField f : this)
|
||||
if (f.getHeader()==header)
|
||||
|
@ -283,6 +301,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public List<String> getValuesList(String name)
|
||||
{
|
||||
lookups++;
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (HttpField f : this)
|
||||
if (f.getName().equalsIgnoreCase(name))
|
||||
|
@ -394,6 +413,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public List<String> getCSV(HttpHeader header,boolean keepQuotes)
|
||||
{
|
||||
lookups++;
|
||||
QuotedCSV values = null;
|
||||
for (HttpField f : this)
|
||||
{
|
||||
|
@ -417,6 +437,7 @@ public class HttpFields implements Iterable<HttpField>
|
|||
*/
|
||||
public List<String> getCSV(String name,boolean keepQuotes)
|
||||
{
|
||||
lookups++;
|
||||
QuotedCSV values = null;
|
||||
for (HttpField f : this)
|
||||
{
|
||||
|
@ -903,6 +924,9 @@ public class HttpFields implements Iterable<HttpField>
|
|||
|
||||
public void clear()
|
||||
{
|
||||
System.err.printf("iterations=%d lookups=%d%n",iterations,lookups);
|
||||
iterations = 0;
|
||||
lookups = 0;
|
||||
_size=0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,11 @@ package org.eclipse.jetty.server.jmh;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayTrie;
|
||||
import org.eclipse.jetty.util.TreeTrie;
|
||||
import org.eclipse.jetty.util.Trie;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
|
@ -48,7 +45,7 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
|
|||
@Threads(1)
|
||||
@Warmup(iterations = 6, time = 2000, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@Measurement(iterations = 3, time = 2000, timeUnit = TimeUnit.MILLISECONDS)
|
||||
public class ListVsTrieBenchmark
|
||||
public class ListVsMapBenchmark
|
||||
{
|
||||
@Param({ "12" }) // Chrome has 12 for HTTP/1.1 and 16 for HTTP/2 (including meta headers)
|
||||
public static int size;
|
||||
|
@ -165,35 +162,28 @@ public class ListVsTrieBenchmark
|
|||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.Throughput})
|
||||
public long testTreeTrie() throws Exception
|
||||
public long testSortedMap() throws Exception
|
||||
{
|
||||
Trie<Pair> trie = new TreeTrie<>();
|
||||
fill(p->trie.put(p.key,p));
|
||||
return test(trie::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.Throughput})
|
||||
public long testArrayTrie() throws Exception
|
||||
Map<String,List<Pair>> map = new LinkedHashMap<>(size);
|
||||
fill(p->
|
||||
{
|
||||
Trie<Pair> trie = new ArrayTrie<>(length*size);
|
||||
fill(p->trie.put(p.key,p));
|
||||
return test(trie::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode({Mode.Throughput})
|
||||
public long testMap() throws Exception
|
||||
List<Pair> list = new ArrayList<>();
|
||||
list.add(p);
|
||||
map.put(p.key.toLowerCase(),list);
|
||||
});
|
||||
return test(k->
|
||||
{
|
||||
Map<String,Pair> map = new HashMap<>(size);
|
||||
fill(p->map.put(p.key.toLowerCase(),p));
|
||||
return test(k->map.get(k.toLowerCase()));
|
||||
List<Pair> list = map.get(k.toLowerCase());
|
||||
if (list==null || list.isEmpty())
|
||||
return null;
|
||||
return list.get(0);
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws RunnerException
|
||||
{
|
||||
Options opt = new OptionsBuilder()
|
||||
.include(ListVsTrieBenchmark.class.getSimpleName())
|
||||
.include(ListVsMapBenchmark.class.getSimpleName())
|
||||
// .addProfiler(GCProfiler.class)
|
||||
.forks(1)
|
||||
.build();
|
Loading…
Reference in New Issue