子平八字生成

1 多线程生成数据 

 @PostMapping("genData")
    public ResponseResult genData(){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
//        int threadPoolSize = Math.min(Runtime.getRuntime().availableProcessors() * 2, 64);
        int threadPoolSize = Runtime.getRuntime().availableProcessors();
        log.info("线程池大小:{}",threadPoolSize);
        ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
        List<CompletableFuture<Void>> futures = new ArrayList<>();

        for (LiuShiJiaZiEnum year : LiuShiJiaZiEnum.values()) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> processYear(year), executor)
                    .exceptionally(ex -> {
                        // 记录异常并返回null以避免中断其他任务
                        log.error("Error processing year " + year, ex);
                        ex.printStackTrace();
                        return null;
                    });
            futures.add(future);
        }

        // 等待所有任务完成,并忽略已经处理过的异常
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        executor.shutdown();
        stopWatch.stop();
        log.info("Execution time: " + stopWatch.getTotalTimeMillis() + " ms");
        return new ResponseResult(true,"生成成功");
    }
private void processYear(LiuShiJiaZiEnum year){
        List<LiuShiJiaZiEnum> months = liuShiJiaZiService.getMonths(year);
        List<LiuShiJiaZiEnum> days = Arrays.asList(LiuShiJiaZiEnum.values());
        List<DiZhiEnum> hzs = Arrays.asList(DiZhiEnum.values());
        int BATCH_SIZE = 1000;
        List<ZpBaziInfo> batch = new ArrayList<>(BATCH_SIZE);
        // 遍历年月日时,生成子平八字信息
        for (LiuShiJiaZiEnum month: months){
            for (LiuShiJiaZiEnum day: days){
                for (DiZhiEnum hz: hzs){
                    LiuShiJiaZiEnum hour = liuShiJiaZiService.getHour(day.getTiangan(), hz);
                    ZpBaziInfo record = genZpBaziInfo(year, month, day, hour);
                    batch.add(record);
                    if (batch.size() >= BATCH_SIZE) {
                        zpBaziInfoService.saveBatch(batch);
                        batch = new ArrayList<>(BATCH_SIZE); // 清空批次以备下一轮
                    }
                }
            }
        }
        if (!batch.isEmpty()) {
            zpBaziInfoService.saveBatch(batch);// 保存最后一批
        }
    }

2 五虎遁

        这里采用的jdk17,我将原来jdk1.8的代码重写了。

   /**
     * 根据年,获取月份
     * @param year
     * @return
     */
    public List<LiuShiJiaZiEnum> getMonths(LiuShiJiaZiEnum year) {
        return switch (year.getTiangan()){
            // 甲己之年丙作首
            case JIA,JI -> calculateMonths(LiuShiJiaZiEnum.BINGYIN);
            // 乙庚之岁戊为头
            case YI,GENG -> calculateMonths(LiuShiJiaZiEnum.WUYIN);
            // 丙辛之岁寻庚起
            case BING,XIN -> calculateMonths(LiuShiJiaZiEnum.GENGYIN);
            // 丁壬壬位顺行流
            case DING,REN -> calculateMonths(LiuShiJiaZiEnum.RENYIN);
            // 若问戊癸何方发,甲寅之上好追求
            case WU,GUI -> calculateMonths(LiuShiJiaZiEnum.JIAYIN);
            default -> throw new IllegalArgumentException("年柱甲子错误");
        };
    }

    /**
     * 推算月柱
     * @param start
     * @return
     */
    private  List<LiuShiJiaZiEnum> calculateMonths(LiuShiJiaZiEnum start){
        return IntStream.range(0,12)
                .mapToObj(i->{
                    int end = start.getValue() + i;
                    end = end>60?end%60:end;
                    return LiuShiJiaZiEnum.getLiuShiJiaZiEnum(end);
                }).collect(Collectors.toList());
    }
/**
     * 根据天干地支获取对应的六十甲子值(五鼠遁日)
     *
     * @param tg 天干枚举
     * @param dz 地支枚举
     * @return 对应的六十甲子枚举值
     */
    public LiuShiJiaZiEnum getHour(TianGanEnum tg, DiZhiEnum dz) {
        /**
         * 甲己还加甲,乙庚丙作初。
         * 丙辛从戊起,丁壬庚子居。
         * 戊癸起壬子,周而复始求
         */
        Map<TianGanEnum, Integer> startOffsets = Map.of(
                TianGanEnum.JIA, 1, TianGanEnum.JI, 1,
                TianGanEnum.YI, 13, TianGanEnum.GENG, 13,
                TianGanEnum.BING, 25, TianGanEnum.XIN, 25,
                TianGanEnum.DING, 37, TianGanEnum.REN, 37,
                TianGanEnum.WU, 49, TianGanEnum.GUI, 49
        );

        Integer offset = startOffsets.get(tg);
        if (offset == null) {
            throw new IllegalArgumentException("Unexpected Tiangan value: " + tg);
        }

        // 计算最终索引并返回对应的 LiuShiJiaZiEnum
        int index = (offset + dz.getValue()-1) % 60;
        return LiuShiJiaZiEnum.values()[index];
    }

经过测试518400条数据,103.63MB数据,耗费5~6ms中写入到数据库。

SELECT 
    table_name AS `Table`,
    round(((data_length + index_length) / 1024 / 1024), 2) AS `Size in MB`
FROM information_schema.TABLES
WHERE table_schema = 'ziping' 
AND table_name = 'zp_bazi_info';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值