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