Browse Source

Perf: optimize sort domains & preload promise

SukkaW 2 years ago
parent
commit
6daf8e3bb4

+ 23 - 7
Build/build-speedtest-domainset.ts

@@ -13,6 +13,9 @@ import picocolors from 'picocolors';
 import { fetchRemoteTextByLine } from './lib/fetch-text-by-line';
 import { processLine } from './lib/process-line';
 import { TTL, deserializeArray, fsCache, serializeArray } from './lib/cache-filesystem';
+import { createMemoizedPromise } from './lib/memo-promise';
+
+import * as SetHelpers from 'mnemonist/set';
 
 const s = new Sema(2);
 
@@ -80,15 +83,26 @@ const querySpeedtestApi = async (keyword: string): Promise<Array<string | null>>
   }
 };
 
+const getPreviousSpeedtestDomainsPromise = createMemoizedPromise(async () => {
+  const domains = new Set<string>();
+  for await (const l of await fetchRemoteTextByLine('https://ruleset.skk.moe/List/domainset/speedtest.conf')) {
+    const line = processLine(l);
+    if (line) {
+      domains.add(line);
+    }
+  }
+  return domains;
+});
+
 export const buildSpeedtestDomainSet = task(import.meta.path, async (span) => {
   // Predefined domainset
   /** @type {Set<string>} */
   const domains = new Set<string>([
+    // speedtest.net
     '.speedtest.net',
     '.speedtestcustom.com',
     '.ooklaserver.net',
     '.speed.misaka.one',
-    '.speed.cloudflare.com',
     '.speedtest.rt.ru',
     '.speedtest.aptg.com.tw',
     '.speedtest.gslnetworks.com',
@@ -133,6 +147,13 @@ export const buildSpeedtestDomainSet = task(import.meta.path, async (span) => {
     '.speedtest.optitel.com.au',
     '.speednet.net.tr',
     '.speedtest.angolacables.co.ao',
+    '.ookla-speedtest.fsr.com',
+    '.speedtest.comnet.com.tr',
+    '.speedtest.gslnetworks.com.au',
+    '.speedtest.gslnetworks.com',
+    '.speedtestunonet.com.br',
+    // Cloudflare
+    '.speed.cloudflare.com',
     // Wi-Fi Man
     '.wifiman.com',
     '.wifiman.me',
@@ -152,12 +173,7 @@ export const buildSpeedtestDomainSet = task(import.meta.path, async (span) => {
   ]);
 
   await span.traceChild('fetch previous speedtest domainset').traceAsyncFn(async () => {
-    for await (const l of await fetchRemoteTextByLine('https://ruleset.skk.moe/List/domainset/speedtest.conf')) {
-      const line = processLine(l);
-      if (line) {
-        domains.add(line);
-      }
-    }
+    SetHelpers.add(domains, await getPreviousSpeedtestDomainsPromise());
   });
 
   await new Promise<void>((resolve) => {

+ 11 - 12
Build/build-stream-service.ts

@@ -9,8 +9,7 @@ import { ALL, NORTH_AMERICA, EU, HK, TW, JP, KR } from '../Source/stream';
 import { SHARED_DESCRIPTION } from './lib/constants';
 
 export const createRulesetForStreamService = (span: Span, fileId: string, title: string, streamServices: Array<import('../Source/stream').StreamService>) => {
-  const childSpan = span.traceChild(fileId);
-  return [
+  return span.traceChild(fileId).traceAsyncFn(async (childSpan) => Promise.all([
     // Domains
     createRuleset(
       childSpan,
@@ -48,20 +47,20 @@ export const createRulesetForStreamService = (span: Span, fileId: string, title:
       path.resolve(import.meta.dir, `../List/ip/${fileId}.conf`),
       path.resolve(import.meta.dir, `../Clash/ip/${fileId}.txt`)
     )
-  ];
+  ]));
 };
 
 export const buildStreamService = task(import.meta.path, async (span) => {
   return Promise.all([
-    ...createRulesetForStreamService(span, 'stream', 'All', ALL),
-    ...createRulesetForStreamService(span, 'stream_us', 'North America', NORTH_AMERICA),
-    ...createRulesetForStreamService(span, 'stream_eu', 'Europe', EU),
-    ...createRulesetForStreamService(span, 'stream_hk', 'Hong Kong', HK),
-    ...createRulesetForStreamService(span, 'stream_tw', 'Taiwan', TW),
-    ...createRulesetForStreamService(span, 'stream_jp', 'Japan', JP),
-    // ...createRulesetForStreamService('stream_au', 'Oceania', AU),
-    ...createRulesetForStreamService(span, 'stream_kr', 'Korean', KR)
-    // ...createRulesetForStreamService('stream_south_east_asia', 'South East Asia', SOUTH_EAST_ASIA)
+    createRulesetForStreamService(span, 'stream', 'All', ALL),
+    createRulesetForStreamService(span, 'stream_us', 'North America', NORTH_AMERICA),
+    createRulesetForStreamService(span, 'stream_eu', 'Europe', EU),
+    createRulesetForStreamService(span, 'stream_hk', 'Hong Kong', HK),
+    createRulesetForStreamService(span, 'stream_tw', 'Taiwan', TW),
+    createRulesetForStreamService(span, 'stream_jp', 'Japan', JP),
+    // createRulesetForStreamService('stream_au', 'Oceania', AU),
+    createRulesetForStreamService(span, 'stream_kr', 'Korean', KR)
+    // createRulesetForStreamService('stream_south_east_asia', 'South East Asia', SOUTH_EAST_ASIA)
   ]);
 });
 

+ 3 - 2
Build/lib/cached-tld-parse.ts

@@ -16,8 +16,9 @@ export const parseWithoutDetectIp = parse2;
 
 let gothillGetDomainCache: ReturnType<typeof createCache> | null = null;
 export const createCachedGorhillGetDomain = (gorhill: PublicSuffixList) => {
+  gothillGetDomainCache ??= createCache('cached-gorhill-get-domain', true);
   return (domain: string) => {
-    gothillGetDomainCache ??= createCache('cached-gorhill-get-domain', true);
-    return gothillGetDomainCache.sync(domain, () => gorhill.getDomain(domain[0] === '.' ? domain.slice(1) : domain));
+    // we do know gothillGetDomainCache exists here
+    return gothillGetDomainCache!.sync(domain, () => gorhill.getDomain(domain[0] === '.' ? domain.slice(1) : domain));
   };
 };

+ 7 - 2
Build/lib/memo-promise.ts

@@ -1,7 +1,12 @@
-export const createMemoizedPromise = <T>(fn: () => Promise<T>): () => Promise<T> => {
+export const createMemoizedPromise = <T>(fn: () => Promise<T>, preload = true): () => Promise<T> => {
   let promise: Promise<T> | null = null;
+
+  if (preload) {
+    promise = fn();
+  }
+
   return () => {
-    promise ||= fn();
+    promise ??= fn();
     return promise;
   };
 };

+ 4 - 8
Build/lib/stable-sort-domain.ts

@@ -35,18 +35,14 @@ const compare = (a: string | null, b: string | null) => {
 
 export const sortDomains = (inputs: string[], gorhill: PublicSuffixList) => {
   const getDomain = createCachedGorhillGetDomain(gorhill);
-  const domains = inputs.reduce<Record<string, string>>((acc, cur) => {
-    acc[cur] ||= getDomain(cur);
+  const domains = inputs.reduce<Map<string, string>>((acc, cur) => {
+    if (!acc.has(cur)) acc.set(cur, getDomain(cur));
     return acc;
-  }, {});
+  }, new Map());
 
   const sorter = (a: string, b: string) => {
     if (a === b) return 0;
-
-    const aDomain = domains[a];
-    const bDomain = domains[b];
-
-    return compare(aDomain, bDomain) || compare(a, b);
+    return compare(domains.get(a)!, domains.get(b)!) || compare(a, b);
   };
 
   return inputs.sort(sorter);