performance improvement: using Queue instead of LinkedList

This commit is contained in:
Mikhail Senkov
2012-01-16 16:08:26 +04:00
parent 052143b4e4
commit b243e257aa
3 changed files with 51 additions and 11 deletions
@@ -17,8 +17,7 @@ package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.ImmutableUserMap;
import java.util.LinkedList;
import com.intellij.util.containers.Queue;
/**
* @author peter
@@ -29,20 +28,27 @@ public abstract class LookAheadLexer extends LexerBase{
private final Lexer myBaseLexer;
private int myTokenStart;
private final LinkedList<IElementType> myTypeCache = new LinkedList<IElementType>();
private final LinkedList<Integer> myEndOffsetCache = new LinkedList<Integer>();
private final Queue<IElementType> myTypeCache;
private final Queue<Integer> myEndOffsetCache;
public LookAheadLexer(final Lexer baseLexer, int capacity) {
myBaseLexer = baseLexer;
myTypeCache = new Queue<IElementType>(capacity);
myEndOffsetCache = new Queue<Integer>(capacity);
}
public LookAheadLexer(final Lexer baseLexer) {
myBaseLexer = baseLexer;
this(baseLexer, 64);
}
protected void addToken(IElementType type) {
addToken(myBaseLexer.getTokenEnd(), type);
}
protected void addToken(int endOffset, IElementType type) {
myTypeCache.add(type);
myEndOffsetCache.add(endOffset);
myTypeCache.addLast(type);
myEndOffsetCache.addLast(endOffset);
}
protected void lookAhead(Lexer baseLexer) {
@@ -51,8 +57,8 @@ public abstract class LookAheadLexer extends LexerBase{
public void advance() {
if (!myTypeCache.isEmpty()) {
myTypeCache.removeFirst();
myTokenStart = myEndOffsetCache.removeFirst();
myTypeCache.pullFirst();
myTokenStart = myEndOffsetCache.pullFirst();
}
if (myTypeCache.isEmpty()) {
doLookAhead();
@@ -92,7 +98,7 @@ public abstract class LookAheadLexer extends LexerBase{
}
public int getTokenEnd() {
return myEndOffsetCache.getFirst();
return myEndOffsetCache.peekFirst();
}
public int getTokenStart() {
@@ -115,7 +121,7 @@ public abstract class LookAheadLexer extends LexerBase{
}
public IElementType getTokenType() {
return myTypeCache.getFirst();
return myTypeCache.peekFirst();
}
@Override
@@ -50,6 +50,18 @@ public class Queue<T> {
myLast = 0;
}
}
public T removeLast() {
if (myLast == 0) {
isWrapped = !isWrapped;
myLast = myArray.length;
}
myLast--;
T result = (T)myArray[myLast];
myArray[myLast] = null;
return result;
}
public boolean isEmpty() {
return size() == 0;
@@ -57,6 +57,28 @@ public class QueueTest extends TestCase {
assertEquals(xxx,x);
assertTrue(queue.isEmpty());
}
public void testRemoving() {
com.intellij.util.containers.Queue queue = new com.intellij.util.containers.Queue(10);
for (int i = 0; i < 9; i++) {
queue.addLast(String.valueOf(i));
}
for (int i = 0; i < 4; i++) {
Object first = queue.pullFirst();
queue.addLast(first);
}
for (int i = 3; i >= 0; i--) {
Assert.assertEquals(String.valueOf(i), queue.removeLast());
}
for (int i = 8; i >= 6; i--) {
Assert.assertEquals(String.valueOf(i), queue.removeLast());
}
for (int i = 4; i <= 5; i++) {
Assert.assertEquals(String.valueOf(i), queue.pullFirst());
}
}
public void testCycling() {
com.intellij.util.containers.Queue queue = new com.intellij.util.containers.Queue(10);
for (int i = 0; i < 9; i++) {