sets.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. import * as B from 'benchmark'
  2. import { Tuple, Segmentation, OrderedSet as OrdSet } from '../mol-data/int'
  3. // import { ElementSet } from 'mol-model/structure'
  4. // export namespace Iteration {
  5. // const U = 1000, V = 2500;
  6. // const control: number[] = [];
  7. // const sets = Object.create(null);
  8. // for (let i = 1; i < U; i++) {
  9. // const set = [];
  10. // for (let j = 1; j < V; j++) {
  11. // control[control.length] = j * j + 1;
  12. // set[set.length] = j * j + 1;
  13. // }
  14. // sets[i * i] = OrdSet.ofSortedArray(set);
  15. // }
  16. // const ms = ElementSet.create(sets);
  17. // export function native() {
  18. // let s = 0;
  19. // for (let i = 0, _i = control.length; i < _i; i++) s += control[i];
  20. // return s;
  21. // }
  22. // export function iterators() {
  23. // let s = 0;
  24. // const it = ElementSet.atoms(ms);
  25. // while (it.hasNext) {
  26. // const v = it.move();
  27. // s += Tuple.snd(v);
  28. // }
  29. // return s;
  30. // }
  31. // export function elementAt() {
  32. // let s = 0;
  33. // for (let i = 0, _i = ElementSet.atomCount(ms); i < _i; i++) s += Tuple.snd(ElementSet.atomGetAt(ms, i));
  34. // return s;
  35. // }
  36. // export function manual() {
  37. // let s = 0;
  38. // const keys = ElementSet.unitIds(ms);
  39. // for (let i = 0, _i = OrdSet.size(keys); i < _i; i++) {
  40. // const set = ElementSet.unitGetById(ms, OrdSet.getAt(keys, i));
  41. // for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
  42. // s += OrdSet.getAt(set, j);
  43. // }
  44. // }
  45. // return s;
  46. // }
  47. // export function manual1() {
  48. // let s = 0;
  49. // for (let i = 0, _i = ElementSet.unitCount(ms); i < _i; i++) {
  50. // const set = ElementSet.unitGetByIndex(ms, i);
  51. // for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
  52. // s += OrdSet.getAt(set, j);
  53. // }
  54. // }
  55. // return s;
  56. // }
  57. // export function run() {
  58. // const suite = new B.Suite();
  59. // // const values: number[] = [];
  60. // // for (let i = 0; i < 1000000; i++) values[i] = (Math.random() * 1000) | 0;
  61. // console.log(Iteration.native(), Iteration.iterators(), Iteration.elementAt(), Iteration.manual(), Iteration.manual1());
  62. // suite
  63. // .add('native', () => Iteration.native())
  64. // .add('iterators', () => Iteration.iterators())
  65. // .add('manual', () => Iteration.manual())
  66. // .add('manual1', () => Iteration.manual1())
  67. // .add('el at', () => Iteration.elementAt())
  68. // .on('cycle', (e: any) => console.log(String(e.target)))
  69. // .run();
  70. // }
  71. // }
  72. export namespace Union {
  73. function createArray(n: number) {
  74. const data = new Int32Array(n);
  75. let c = (Math.random() * 100) | 0;
  76. for (let i = 0; i < n; i++) {
  77. data[i] = c;
  78. c += 1 + (Math.random() * 100) | 0
  79. }
  80. return data;
  81. }
  82. function rangeArray(o: number, n: number) {
  83. const data = new Int32Array(n);
  84. for (let i = 0; i < n; i++) {
  85. data[i] = o + i;
  86. }
  87. return data;
  88. }
  89. function createData(array: ArrayLike<number>) {
  90. const obj = Object.create(null);
  91. const set = new Set<number>();
  92. for (let i = 0; i < array.length; i++) {
  93. const a = array[i];
  94. obj[a] = 1;
  95. set.add(a);
  96. }
  97. return { ordSet: OrdSet.ofSortedArray(array), obj, set }
  98. }
  99. function unionOS(a: OrdSet, b: OrdSet) {
  100. return OrdSet.union(a, b);
  101. }
  102. function intOS(a: OrdSet, b: OrdSet) {
  103. return OrdSet.intersect(a, b);
  104. }
  105. function unionO(a: object, b: object) {
  106. const ret = Object.create(null);
  107. for (const k of Object.keys(a)) ret[k] = 1;
  108. for (const k of Object.keys(b)) ret[k] = 1;
  109. return ret;
  110. }
  111. function intO(a: object, b: object) {
  112. const ret = Object.create(null);
  113. for (const k of Object.keys(a)) if ((b as any)[k]) ret[k] = 1;
  114. return ret;
  115. }
  116. function _setAdd(this: Set<number>, x: number) { this.add(x) }
  117. function unionS(a: Set<number>, b: Set<number>) {
  118. const ret = new Set<number>();
  119. a.forEach(_setAdd, ret);
  120. b.forEach(_setAdd, ret);
  121. return ret;
  122. }
  123. function _setInt(this: { set: Set<number>, other: Set<number> }, x: number) { if (this.other.has(x)) this.set.add(x) }
  124. function intS(a: Set<number>, b: Set<number>) {
  125. if (a.size < b.size) {
  126. const ctx = { set: new Set<number>(), other: b };
  127. a.forEach(_setInt, ctx);
  128. return ctx.set;
  129. } else {
  130. const ctx = { set: new Set<number>(), other: a };
  131. b.forEach(_setInt, ctx);
  132. return ctx.set;
  133. }
  134. }
  135. export function run() {
  136. const suite = new B.Suite();
  137. const { ordSet: osA, set: sA, obj: oA } = createData(createArray(1000));
  138. const { ordSet: osB, set: sB, obj: oB } = createData(createArray(1000));
  139. console.log(OrdSet.size(unionOS(osA, osB)), Object.keys(unionO(oA, oB)).length, unionS(sA, sB).size);
  140. console.log(OrdSet.size(intOS(osA, osB)), Object.keys(intO(oA, oB)).length, intS(sA, sB).size);
  141. suite
  142. .add('u ord set', () => unionOS(osA, osB))
  143. .add('u obj', () => unionO(oA, oB))
  144. .add('u ES6 set', () => unionS(sA, sB))
  145. .add('i ord set', () => intOS(osA, osB))
  146. .add('i obj', () => intO(oA, oB))
  147. .add('i ES6 set', () => intS(sA, sB))
  148. .on('cycle', (e: any) => console.log(String(e.target)))
  149. .run();
  150. }
  151. export function runR() {
  152. const suite = new B.Suite();
  153. const rangeA = rangeArray(145, 1000);
  154. const rangeB = rangeArray(456, 1000);
  155. const { ordSet: osA, set: sA, obj: oA } = createData(rangeA);
  156. const { ordSet: osB, set: sB, obj: oB } = createData(rangeB);
  157. console.log(OrdSet.size(unionOS(osA, osB)), Object.keys(unionO(oA, oB)).length, unionS(sA, sB).size);
  158. console.log(OrdSet.size(intOS(osA, osB)), Object.keys(intO(oA, oB)).length, intS(sA, sB).size);
  159. suite
  160. .add('u ord set', () => unionOS(osA, osB))
  161. .add('u obj', () => unionO(oA, oB))
  162. .add('u ES6 set', () => unionS(sA, sB))
  163. .add('i ord set', () => intOS(osA, osB))
  164. .add('i obj', () => intO(oA, oB))
  165. .add('i ES6 set', () => intS(sA, sB))
  166. .on('cycle', (e: any) => console.log(String(e.target)))
  167. .run();
  168. }
  169. }
  170. // export namespace Build {
  171. // function createSorted() {
  172. // const b = ElementSet.LinearBuilder(ElementSet.Empty);
  173. // for (let i = 0; i < 10; i++) {
  174. // for (let j = 0; j < 1000; j++) {
  175. // b.add(i, j);
  176. // }
  177. // }
  178. // return b.getSet();
  179. // }
  180. // function createByUnit() {
  181. // const b = ElementSet.LinearBuilder(ElementSet.Empty);
  182. // for (let i = 0; i < 10; i++) {
  183. // b.beginUnit();
  184. // for (let j = 0; j < 1000; j++) {
  185. // b.addToUnit(j);
  186. // }
  187. // b.commitUnit(i);
  188. // }
  189. // return b.getSet();
  190. // }
  191. // export function run() {
  192. // const suite = new B.Suite();
  193. // suite
  194. // .add('create sorted', () => createSorted())
  195. // .add('create by unit', () => createByUnit())
  196. // .on('cycle', (e: any) => console.log(String(e.target)))
  197. // .run();
  198. // }
  199. // }
  200. export namespace Tuples {
  201. function createData(n: number) {
  202. const ret: Tuple[] = new Float64Array(n) as any;
  203. for (let i = 0; i < n; i++) {
  204. ret[i] = Tuple.create(i, i * i + 1);
  205. }
  206. return ret;
  207. }
  208. function sum1(data: ArrayLike<Tuple>) {
  209. let s = 0;
  210. for (let i = 0, _i = data.length; i < _i; i++) {
  211. s += Tuple.fst(data[i]) + Tuple.snd(data[i]);
  212. }
  213. return s;
  214. }
  215. function sum2(data: ArrayLike<Tuple>) {
  216. let s = 0;
  217. for (let i = 0, _i = data.length; i < _i; i++) {
  218. const t = data[i];
  219. s += Tuple.fst(t) + Tuple.snd(t);
  220. }
  221. return s;
  222. }
  223. export function run() {
  224. const suite = new B.Suite();
  225. const data = createData(10000);
  226. suite
  227. .add('sum fst/snd', () => sum1(data))
  228. .add('sum fst/snd 1', () => sum2(data))
  229. .on('cycle', (e: any) => console.log(String(e.target)))
  230. .run();
  231. }
  232. }
  233. export function testSegments() {
  234. const data = OrdSet.ofSortedArray([4, 9, 10, 11, 14, 15, 16]);
  235. const segs = Segmentation.create([0, 4, 10, 12, 13, 15, 25]);
  236. const it = Segmentation.transientSegments(segs, data);
  237. while (it.hasNext) {
  238. const s = it.move();
  239. for (let j = s.start; j < s.end; j++) {
  240. console.log(`${s.index}: ${OrdSet.getAt(data, j)}`);
  241. }
  242. }
  243. }
  244. export namespace ObjectVsMap {
  245. function objCreate(keys: string[]) {
  246. const m = Object.create(null);
  247. m.x = 0;
  248. delete m.x;
  249. for (let i = 0, _i = keys.length; i < _i; i++) {
  250. m[keys[i]] = i * i;
  251. }
  252. return m;
  253. }
  254. function mapCreate(keys: string[]) {
  255. const m = new Map<string, number>();
  256. for (let i = 0, _i = keys.length; i < _i; i++) {
  257. m.set(keys[i], i * i);
  258. }
  259. return m;
  260. }
  261. function objQuery(keys: string[], n: number, obj: any) {
  262. let ret = 0;
  263. for (let i = 0; i < n; i++) ret += obj[keys[i % n]];
  264. return ret;
  265. }
  266. function mapQuery(keys: string[], n: number, map: Map<string, number>) {
  267. let ret = 0;
  268. for (let i = 0; i < n; i++) ret += map.get(keys[i % n])!;
  269. return ret;
  270. }
  271. export function run() {
  272. const suite = new B.Suite();
  273. const keys: string[] = [];
  274. for (let i = 0; i < 1000; i++) keys[i] = 'k' + i;
  275. const N = 100000;
  276. const obj = objCreate(keys);
  277. const map = mapCreate(keys);
  278. suite
  279. .add('c obj', () => objCreate(keys))
  280. .add('c map', () => mapCreate(keys))
  281. .add('q obj', () => objQuery(keys, N, obj))
  282. .add('q map', () => mapQuery(keys, N, map))
  283. .on('cycle', (e: any) => console.log(String(e.target)))
  284. .run();
  285. }
  286. }
  287. export namespace IntVsStringIndices {
  288. type WithKeys<K> = { keys: K[], data: { [key: number]: number } }
  289. type MapWithKeys = { keys: number[], map: Map<number, number> }
  290. function createCacheKeys(n: number): WithKeys<number> {
  291. const data = Object.create(null), keys = [];
  292. data.__ = void 0;
  293. delete data.__;
  294. for (let i = 1; i <= n; i++) {
  295. const k = i * (i + 1);
  296. keys[keys.length] = k;
  297. data[k] = i + 1;
  298. }
  299. return { data, keys };
  300. }
  301. function createMapKeys(n: number): MapWithKeys {
  302. const map = new Map<number, number>(), keys = [];
  303. for (let i = 1; i <= n; i++) {
  304. const k = i * (i + 1);
  305. keys[keys.length] = k;
  306. map.set(k, i + 1);
  307. }
  308. return { map, keys };
  309. }
  310. export function createInt(n: number) {
  311. const ret = Object.create(null);
  312. ret.__ = void 0;
  313. delete ret.__;
  314. for (let i = 1; i <= n; i++) ret[i * (i + 1)] = i + 1;
  315. return ret;
  316. }
  317. export function createStr(n: number) {
  318. const ret = Object.create(null);
  319. ret.__ = void 0;
  320. delete ret.__;
  321. for (let i = 1; i <= n; i++) ret['' + (i * (i + 1))] = i + 1;
  322. return ret;
  323. }
  324. export function createMap(n: number) {
  325. const map = new Map<number, number>();
  326. for (let i = 1; i <= n; i++) map.set(i * (i + 1), i + 1);
  327. return map;
  328. }
  329. export function sumInt(xs: { [key: number]: number }) {
  330. let s = 0;
  331. const keys = Object.keys(xs);
  332. for (let i = 0, _i = keys.length; i < _i; i++) s += xs[+keys[i]];
  333. return s;
  334. }
  335. export function sumStr(xs: { [key: string]: number }) {
  336. let s = 0;
  337. const keys = Object.keys(xs);
  338. for (let i = 0, _i = keys.length; i < _i; i++) s += xs[keys[i]];
  339. return s;
  340. }
  341. export function sumMap(map: Map<number, number>) {
  342. let s = 0;
  343. const values = map.keys();
  344. while (true) {
  345. const { done, value } = values.next();
  346. if (done) break;
  347. s += value;
  348. }
  349. return s;
  350. }
  351. export function sumCached(xs: WithKeys<number>) {
  352. let s = 0;
  353. const keys = xs.keys, data = xs.data;
  354. for (let i = 0, _i = keys.length; i < _i; i++) s += data[keys[i]];
  355. return s;
  356. }
  357. export function sumKeyMap(xs: MapWithKeys) {
  358. let s = 0;
  359. const keys = xs.keys, map = xs.map;
  360. for (let i = 0, _i = keys.length; i < _i; i++) s += map.get(keys[i])!;
  361. return s;
  362. }
  363. export function run() {
  364. const N = 1000;
  365. // const int = createInt(N);
  366. const map = createMap(N);
  367. // const str = createStr(N);
  368. const keys = createCacheKeys(N);
  369. const keyMap = createMapKeys(N);
  370. console.log(sumMap(map), sumCached(keys), sumKeyMap(keyMap));
  371. new B.Suite()
  372. // .add('c int', () => createInt(N))
  373. .add('q map', () => sumMap(map))
  374. .add('c map', () => createMap(N))
  375. .add('c mk', () => createMapKeys(N))
  376. // .add('c str', () => createStr(N))
  377. .add('c cc', () => createCacheKeys(N))
  378. // .add('q int', () => sumInt(int))
  379. .add('q mk', () => sumKeyMap(keyMap))
  380. // .add('q str', () => sumStr(str))
  381. .add('q cc', () => sumCached(keys))
  382. .on('cycle', (e: any) => console.log(String(e.target)))
  383. .run();
  384. }
  385. }
  386. IntVsStringIndices.run();
  387. // ObjectVsMap.run();
  388. // testSegments();
  389. // Tuples.run();
  390. // interface AA { kind: 'a' }
  391. // //interface BB { kind: 'b' }
  392. // interface AB { kind: 'a' | 'b' }
  393. // declare const a: AA;
  394. // export const ab: AB = a;