优化实体列表add/remove效率。性能大幅度提高

This commit is contained in:
yhh
2021-04-16 17:48:13 +08:00
parent 5a6d1c72fe
commit 17b36f01b0
14 changed files with 1494 additions and 211 deletions

View File

@@ -0,0 +1,158 @@
module es {
export class Bag<E> implements ImmutableBag<E> {
public size_ = 0;
public length = 0;
private array: Array<E> = [];
constructor(capacity = 64) {
this.length = capacity;
}
removeAt(index: number): E {
const e: E = this.array[index];
this.array[index] = this.array[--this.size_];
this.array[this.size_] = null;
return e;
}
remove(e: E): boolean {
let i: number;
let e2: E;
const size = this.size_;
for (i = 0; i < size; i++) {
e2 = this.array[i];
if (e == e2) {
this.array[i] = this.array[--this.size_];
this.array[this.size_] = null;
return true;
}
}
return false;
}
removeLast(): E {
if (this.size_ > 0) {
const e: E = this.array[--this.size_];
this.array[this.size_] = null;
return e;
}
return null;
}
contains(e: E): boolean {
let i: number;
let size: number;
for (i = 0, size = this.size_; size > i; i++) {
if (e === this.array[i]) {
return true;
}
}
return false;
}
removeAll(bag: ImmutableBag<E>): boolean {
let modified = false;
let i: number;
let j: number;
let l: number;
let e1: E;
let e2: E;
for (i = 0, l = bag.size(); i < l; i++) {
e1 = bag[i];
for (j = 0; j < this.size_; j++) {
e2 = this.array[j];
if (e1 === e2) {
this.removeAt(j);
j--;
modified = true;
break;
}
}
}
return modified;
}
get(index: number): E {
if (index >= this.length) {
throw new Error("ArrayIndexOutOfBoundsException");
}
return this.array[index];
}
safeGet(index: number): E {
if (index >= this.length) {
this.grow((index * 7) / 4 + 1);
}
return this.array[index];
}
size(): number {
return this.size_;
}
getCapacity(): number {
return this.length;
}
isIndexWithinBounds(index: number): boolean {
return index < this.getCapacity();
}
isEmpty(): boolean {
return this.size_ == 0;
}
add(e: E): void {
if (this.size_ === this.length) {
this.grow();
}
this.array[this.size_++] = e;
}
set(index: number, e: E): void {
if (index >= this.length) {
this.grow(index * 2);
}
this.size_ = index + 1;
this.array[index] = e;
}
grow(newCapacity: number = ~~((this.length * 3) / 2) + 1): void {
this.length = ~~newCapacity;
}
ensureCapacity(index: number): void {
if (index >= this.length) {
this.grow(index * 2);
}
}
clear(): void {
let i: number;
let size: number;
for (i = 0, size = this.size_; i < size; i++) {
this.array[i] = null;
}
this.size_ = 0;
}
addAll(items: ImmutableBag<E>): void {
let i: number;
for (i = 0; items.size() > i; i++) {
this.add(items.get(i));
}
}
}
}

View File

@@ -0,0 +1,119 @@
module es {
interface Map<K, V> {
clear(): void;
containsKey(key): boolean;
containsValue(value): boolean;
get(key): V;
isEmpty(): boolean;
put(key, value): void;
remove(key): V;
size(): number;
values(): V[];
}
function decode(key): string {
switch (typeof key) {
case "boolean":
return "" + key;
case "number":
return "" + key;
case "string":
return "" + key;
case "function":
return getClassName(key);
default:
key.uuid = key.uuid ? key.uuid : UUID.randomUUID();
return key.uuid;
}
}
export class HashMap<K, V> implements Map<K, V> {
private map_;
private keys_;
constructor() {
this.clear();
}
clear(): void {
this.map_ = {};
this.keys_ = {};
}
values(): V[] {
const result = [];
const map = this.map_;
for (const key in map) {
result.push(map[key]);
}
return result;
}
contains(value): boolean {
const map = this.map_;
for (const key in map) {
if (value === map[key]) {
return true;
}
}
return false;
}
containsKey(key): boolean {
return decode(key) in this.map_;
}
containsValue(value): boolean {
const map = this.map_;
for (const key in map) {
if (value === map[key]) {
return true;
}
}
return false;
}
get(key: K): V {
return this.map_[decode(key)];
}
isEmpty(): boolean {
return Object.keys(this.map_).length === 0;
}
keys(): K[] {
const keys = this.map_;
const result = [];
for (const key in keys) {
result.push(keys[key]);
}
return result;
}
/**
* if key is a string, use as is, else use key.id_ or key.name
*/
put(key, value): void {
const k = decode(key);
this.map_[k] = value;
this.keys_[k] = key;
}
remove(key): V {
const map = this.map_;
const k = decode(key);
const value = map[k];
delete map[k];
delete this.keys_[k];
return value;
}
size(): number {
return Object.keys(this.map_).length;
}
}
}

View File

@@ -0,0 +1,11 @@
module es {
export interface ImmutableBag<E> {
get(index: number): E;
size(): number;
isEmpty(): boolean;
contains(e: E): boolean;
}
}