使用 Trae 进行代码优化

1. 前言

在开发中,我们经常遇到代码的性能、可复用等需要进行优化,这就需要一个对代码比较熟悉的人来完成,但是随着 AI 越来越完善,现在这些优化工作,我们可以交给 AI 来完成,我们只需要告诉它优化的内容,下边我以实例来说明。

2. 给缓存添加有效时间工具优化

优化前代码。

typescript 复制代码
enum DefaultValidTime {
  DefaultTime = 'forever',
  __expiryTime__ = '__expiryTime__'
}
type Key = string
type ValidTime = DefaultValidTime.DefaultTime | number
type StorageData<T> = {
  value: T
  [DefaultValidTime.__expiryTime__]: ValidTime
}
type ValueData<T> = T | null
type Data<T> = {
  msg: string
  value: ValueData<T>
}
interface StorageClass {
  set: <T>(key: Key, value: T, validTime: ValidTime) => void
  get: <T>(key: Key) => Data<T>
  getValue: <T>(key: Key) => ValueData<T>
  remove: (key: Key) => void
  clear: () => void
}

export class UtilStorage implements StorageClass {
  set<T>(key: Key, value: T, validTime: ValidTime = DefaultValidTime.DefaultTime) {
    let expiryTime = validTime
    if (typeof validTime === 'number' && validTime > 0) {
      expiryTime = new Date().getTime() + validTime
    }
    let data:StorageData<T> = {
      value,
      [DefaultValidTime.__expiryTime__]: expiryTime
    }
    localStorage.setItem(key, JSON.stringify(data))
  }
  getValue<T>(key: Key): ValueData<T> {
    let res: Data<T> = this.get(key);
    return res.value;
  }
  get<T>(key: Key): Data<T> {
    const result = localStorage.getItem(key)
    if (result) {
      const data:StorageData<T> = JSON.parse(result)
      const expiryTime = data[DefaultValidTime.__expiryTime__]
      if (
        expiryTime === DefaultValidTime.DefaultTime ||
        (typeof expiryTime === 'number' && expiryTime > +new Date())
      ) {
        return {
          msg: 'success',
          value: data.value
        }
      }
      this.remove(key)
      return {
        msg: key + ' has expired.',
        value: null
      }
    } else {
      return {
        msg: `${key} not found in storage.`,
        value: null
      }
    }
  }
  remove(key: Key) {
    localStorage.removeItem(key)
  }
  clear() {
    localStorage.clear()
  }
}

2.1 优化方向

从缓存和从变量获取,那个更加节约性能?

从它的回答我们可以看出,这个优化方向还是有一定的性价比,但是对于小数据量完全没必要,但是既然是工具,也尽量完善,万一后期其他人使用的时候需要到了呢?就像我之前开发一个微信小程序渲染人员列表,一下返回三万多条数据,接口慢不说,直接渲染到界面都要好几十秒,这些都是我们需要优化的,先做好可能出现的问题,避免问题的发生。

2.2 使用 WeakMap 进行优化

这里我们可以看到,直接让它进行优化,它使用的是 WeakMap,避免内存泄漏。但是随之问题也来了,就是我们存储的时候,key 其实是一个字符串,而 WeakMap 的 key 是弱引用。因此还需要告诉他对 key 进行处理。

2.3 优化 key 是字符串问题

依然使用 WeakMap,key是字符串得情况下如何优化。

2.4 优化后代码

kotlin 复制代码
// ... 其他代码保持不变 ...

export class UtilStorage implements StorageClass {
  private memoryCache = new WeakMap<object, StorageData<any>>();  // 使用 WeakMap
  private keyMap = new Map<Key, object>();  // 用于存储字符串 key 到对象的映射

  set<T>(key: Key, value: T, validTime: ValidTime = DefaultValidTime.DefaultTime) {
    let expiryTime = validTime;
    if (typeof validTime === 'number' && validTime > 0) {
      expiryTime = new Date().getTime() + validTime;
    }
    const data: StorageData<T> = {
      value,
      [DefaultValidTime.__expiryTime__]: expiryTime
    };

    // 获取或创建 key 对应的对象
    let keyObj = this.keyMap.get(key);
    if (!keyObj) {
      keyObj = {};
      this.keyMap.set(key, keyObj);
    }

    this.memoryCache.set(keyObj, data);  // 使用对象作为 WeakMap 的键
    localStorage.setItem(key, JSON.stringify(data));
  }

  get<T>(key: Key): Data<T> {
    const keyObj = this.keyMap.get(key);
    if (keyObj && this.memoryCache.has(keyObj)) {
      const data = this.memoryCache.get(keyObj)!;
      return this.checkExpiry(key, data);
    }

    const result = localStorage.getItem(key);
    if (result) {
      const data: StorageData<T> = JSON.parse(result);
      const keyObj = this.keyMap.get(key) || {};
      this.memoryCache.set(keyObj, data);
      this.keyMap.set(key, keyObj);
      return this.checkExpiry(key, data);
    }

    return {
      msg: `${key} not found in storage.`,
      value: null
    };
  }

  remove(key: Key) {
    const keyObj = this.keyMap.get(key);
    if (keyObj) {
      this.memoryCache.delete(keyObj);
    }
    this.keyMap.delete(key);
    localStorage.removeItem(key);
  }

  clear() {
    this.memoryCache = new WeakMap();
    this.keyMap.clear();
    localStorage.clear();
  }
}

2.5 总结

  1. 使用变量和缓存同时存储,在变量中存在时直接访问变量,这样使访问效率更高;
  2. 使用 WeakMap 避免了内存的泄露,但是 WeakMap 的 key 又必须是弱引用,key 又是字符串,因此将 key 处理成对象;
  3. 添加一个 Map 将传入的 key 处理成对象,存入到 Map 中;
  4. 当然这是它处理的结果,如果是我处理的话,直接在第二步就是使用 Map 进行处理,来管理缓存数据的访问。

3. 重复操作提取辅助函数

我之前使用 Trae 实现过一个工具【使用 Trae 的 Builder 模式实现【自动批量处理图片:添加地理位置和时间信息】脚本】,它里边的代码就存在一些重复操作的代码,但是它写了很多遍,因此我提取部分样例进行优化操作。

3.1 源码

css 复制代码
    draw.text((left + shadow_offset, y_pos + shadow_offset), text_opts['date'], font=font, fill=shadow_color)
    draw.text((left + shadow_offset, y_pos + shadow_offset + (text_height + line_spacing)), text_opts['lat_lng'], font=font, fill=shadow_color)
    draw.text((left + shadow_offset, y_pos + shadow_offset + 2 * (text_height + line_spacing)), address, font=font, fill=shadow_color)
    
    # 绘制白色文本
    draw.text((left, y_pos), text_opts['date'], font=font, fill=text_color)
    y_pos += (text_height + line_spacing)
    draw.text((left, y_pos), text_opts['lat_lng'], font=font, fill=text_color)
    y_pos += (text_height + line_spacing)
    draw.text((left, y_pos), address, font=font, fill=text_color)

通过上边文字的绘制,我们可以看到它在绘制文本和绘制文本阴影其实差不多,但是相当于每一次的文本绘制它都写了两遍,因此我们对其进行优化处理。

3.2 提炼优化

对相同操作的代码进行提炼优化。

3.3 优化后代码

ini 复制代码
# ... existing code ...

def draw_text_with_shadow(draw, x, y, text, font, text_color, shadow_color, shadow_offset):
    # 绘制阴影
    draw.text((x + shadow_offset, y + shadow_offset), text, font=font, fill=shadow_color)
    # 绘制主文本
    draw.text((x, y), text, font=font, fill=text_color)

def add_text_to_image(image_path, out_path, out_image_path, text_opts):
    # ... existing code ...
    
    # 绘制带阴影的文本
    draw_text_with_shadow(draw, left, y_pos, text_opts['date'], font, text_color, shadow_color, shadow_offset)
    y_pos += (text_height + line_spacing)
    draw_text_with_shadow(draw, left, y_pos, text_opts['lat_lng'], font, text_color, shadow_color, shadow_offset)
    y_pos += (text_height + line_spacing)
    draw_text_with_shadow(draw, left, y_pos, address, font, text_color, shadow_color, shadow_offset)
    
    # ... existing code ...

3.4 总结

  1. 可以看到优化后,直接将绘制阴影和绘制文本放在了同一个函数,只是通过传入的参数,进行阴影和文本的不同绘制;
  2. 最后直接调用阴影和文本的统一绘制函数,只需要维护这一个函数的绘制,后期又其他改变,比如不需要阴影等,直接处理这个函数的代码,就不用每个文字的绘制都需要处理了。

4. 总结

  1. 当然类似的优化问题还有很多,比如首屏加载时间的优化、编译优化、打包优化、算法优化等等;
  2. 这些优化通过 AI 一个是能够给我提供给多的解决办法、一个有了优化方向,直接使用它来进行优化,能够减少我们大量的重复工作量;
  3. 就比如一个系统的弹窗UI优化,几十个弹窗,不同人开发的,遇到那种总是喜欢开发自己组件的人,你在优化的时候打死他的冲动都有,这会儿使用 AI 进行优化,就能大大提高你的效率,估计一周都搞不定的事情,现在你一天都可以完成。

5. 其他

当你改变不了这个世界的时候,你就只能跟着他完善自己,由于 AI 的完善,现在都是懵逼的,不知道该何去何从,始终处于迷茫中,现在除了学会使用它,我好像也没有更好的办法了。就比如我实现的【使用 Trae 的 Builder 模式实现【自动批量处理图片:添加地理位置和时间信息】脚本】工具,现在使用 Trae 完成,最多一早上就能完成,但是我之前写了一个类似的工具【【Python 实战】---- 批量对图片添加不同水印】,我记得当时差不多用了我下班时间的三四天。一个是你不熟悉,需要查询这个库的使用方法,要测试实现效果,实现后如果中间其他需求不满足,又需要还根据需求还其他库实现。但是现在 AI 直接都不需要你熟悉这些,它会直接给你实现出效果,你直接根据效果去不断的调试。效率提高了不是一点半点了,所以一度怀疑自己的工作没有什么用处,因为你学习超不过它,比如开发vscode 插件、谷歌浏览器插件、桌面应用等等,每一种都需要你去学习,这些都是需要成本的,但是现在不需要了,只需要你能大概看懂代码,知道问题可能在哪里,告诉它进行优化或者解决就可以。随着 AI 的最终成熟,可能都不需要我们这些一线代码人员了,只需要一个产品,能够给他描述清楚需求,然后有个维护代码的开发人员,能够定位问题就是了。那么我们能够干什么呢?目前我还没找到答案。

相关推荐
cpp加油站2 小时前
Anthropic断供Claude只是续集!AI编程的剿杀战,早被微软按下启动键
ai编程·claude·trae
it董卓2 小时前
Trae 产品体验:开启 AI 编程新旅程
trae
君若雅3 小时前
我如何借助 Trae 三分钟搞定开源项目中的隐藏 BUG
java·后端·trae
Goboy6 小时前
Trae 与颜色板生成器,为前端开发提供智能配色解决方案
ai编程·trae
Goboy6 小时前
Trae 开发文本大小写转换器,结合 MCP Server 自动部署
ai编程·trae
银空飞羽18 小时前
再学学MCP间接提示词注入
安全·mcp·trae
盏灯1 天前
Trae Agent —— 🥘 世纪难题,今晚吃啥?🍳
ai编程·trae
cpp加油站1 天前
发现宝藏:腾讯EdgeOne Pages & 掘金MCP,Trae内一键部署网页(玩转100个MCP系列第一弹)
ai编程·mcp·trae
cpp加油站1 天前
(保姆级教程)Trae中使用clangd插件实现c++代码函数列表、变量补全、代码跳转等功能
c++·ai编程·trae
康伯巴奇1 天前
关于我用AI10分钟做了一个网站这件事
trae