網站建設寫代碼自己怎么創(chuàng)業(yè)附近哪里有計算機培訓班
目錄
- 前情提要
- 遺留問題
- 解決方案
- 優(yōu)化查詢速度
- 優(yōu)化ivf初始化的速度
- 下一步
前情提要
果蔬識別系統(tǒng)性能優(yōu)化之路(二)
遺留問題
- 優(yōu)化同步速度,目前大約30秒,不是一個生產速度
這次來解決遺留問題
通過console,發(fā)現(xiàn)兩個地方特別耗時,一個是查詢數(shù)據(jù),另一個是初始化ivf
/*** 同步redis* @param storeCode*/async syncRedis(storeCode: string) {let s = Date.now();const featureDatabase = await this.findAll(storeCode);let e = Date.now();console.log(`查詢耗時1:${e - s}ms`);const ids = featureDatabase.map(({ id }) => id);await this.redisService.set(`${storeCode}-featureDatabase`, JSON.stringify(ids));s = Date.now();const url = 'http://localhost:5000/sync'; // Python 服務的 URLawait firstValueFrom(this.httpService.post(url, { data: featureDatabase, storeCode }));e = Date.now();console.log(`查詢耗時3:${e - s}ms`);}
解決方案
優(yōu)化查詢速度
之前使用的是FIND_IN_SET方法對類似1,2,3這樣的數(shù)據(jù)進行包含條件的查詢,速度太慢了,優(yōu)化后:
/*** 查詢所有* @param storeCode*/async findAll(storeCode: string) {return await this.featureRepository.createQueryBuilder('feature').select(['feature.id', 'feature.features']).where('feature.storeCode REGEXP :storeCode', { storeCode: `(^|,)${storeCode}(,|$)` }).getMany();}
效果提升了一倍:
優(yōu)化ivf初始化的速度
當前的初始化方法
def __init__(self, features, nlist=100, m=16, n_bits=8):d = features.shape[1]# 創(chuàng)建量化器quantizer = faiss.IndexFlatL2(d) # 使用L2距離進行量化self.index = faiss.IndexIVFPQ(quantizer, d, nlist, m, n_bits)# 訓練索引self.index.train(features)self.index.add(features) # 將特征向量添加到索引中
優(yōu)化方法:
- 增加并行化處理
# 設置線程數(shù),例如使用所有可用的CPU核心
faiss.omp_set_num_threads(num_threads) # num_threads 是你希望使用的線程數(shù)量
- 減少索引的復雜度
減少nlist和m的值,但這樣會損失精度,先不采用 - 使用增量添加數(shù)據(jù)
分批處理可以分散壓力,同時利用數(shù)據(jù)流式處理的優(yōu)勢。
batch_size = 1000 # 每次處理1000個特征
for i in range(0, len(features), batch_size):self.index.add(features[i:i+batch_size])
- 更換其他索引類型
self.index = faiss.IndexIVFFlat(quantizer, d, nlist)
下一步
- 新建store_feature表,關聯(lián)storeCode和featureId表,對數(shù)據(jù)庫進行規(guī)范化,創(chuàng)建一個新的表來映射storeCode與feature的關系,從而可以使用簡單的WHERE條件來充分利用索引
- 實現(xiàn)對特征向量ivf的增刪改查