/*
 * enableDynamicScriptOptimization 第五节性能测试
 * 适用版本：DolphinDB 3.00.6
 *
 * 覆盖使用教程第五节的 11 个已验证场景。
 * 每个场景均按“关闭优化 -> 开启优化”顺序执行，输出计时结果，
 * 并对两种状态下的确定性计算结果进行一致性校验。
 *
 * 前置条件：以管理员身份在目标执行节点的新会话中运行。
 */

// ---------- 公共校验函数 ----------
def checkSameResult(scene, offValue, onValue){
    if(offValue == onValue){
        print(scene + ": 结果一致，通过校验。")
    } else {
        throw scene + ": 关闭和开启优化后的结果不一致。"
    }
}

// ---------- 场景 1：调用链封装在函数体内（100 万次） ----------
def chainStep1(x){ return x + 1 }
def chainStep2(x){ return chainStep1(x) + 2 }
def chainStep3(x){ return chainStep2(x) + 3 }
def scenarioChainInFunction(){
    n = 1000000
    result = 0.0
    for(i in 0..(n-1)){
        result += chainStep3(double(i))
    }
    return result
}

// ---------- 场景 2：循环内并列调用 3 个函数（100 万次） ----------
def parallelFuncA(x){ return x + 1 }
def parallelFuncB(x){ return x * 2 }
def parallelFuncC(x){ return x * x }
def scenarioParallelFunctions(){
    n = 1000000
    result = 0.0
    for(i in 0..(n-1)){
        valueA = parallelFuncA(double(i))
        valueB = parallelFuncB(double(i))
        valueC = parallelFuncC(double(i))
        result += valueA + valueB + valueC
    }
    return result
}

// ---------- 场景 3：单层自定义函数调用循环（100 万次） ----------
def singleLayerCalc(x, y){ return x * x + y * y + x * y }
def scenarioSingleFunctionCall(){
    n = 1000000
    result = array(DOUBLE, n)
    for(i in 0..(n-1)){
        result[i] = singleLayerCalc(double(i), double(i) + 1)
    }
    return sum(result)
}

// ---------- 场景 4：lambda 表达式循环调用（100 万次） ----------
def scenarioLambdaCall(){
    n = 1000000
    calc = def(x){ return x * x - x + 1 }
    result = array(DOUBLE, n)
    for(i in 0..(n-1)){
        result[i] = calc(double(i))
    }
    return sum(result)
}

// ---------- 场景 5：do-while 循环（100 万次） ----------
def scenarioDoWhile(){
    n = 1000000
    i = 0
    result = 0.0
    do {
        result += i * 1.1
        i += 1
    } while(i < n)
    return result
}

// ---------- 场景 6：while 循环（100 万次） ----------
def scenarioWhile(){
    n = 1000000
    i = 0
    result = 0.0
    while(i < n){
        result += i * 1.1
        i += 1
    }
    return result
}

// ---------- 场景 7：VWAP 累计计算（50 万条） ----------
def scenarioVwap(){
    n = 500000
    prices = 50.0 + double((1..n) % 100)
    volumes = 1000 + (1..n) % 10000
    cumVol = 0.0
    cumPV = 0.0
    vwap = array(DOUBLE, n)
    for(i in 0..(n-1)){
        cumVol += volumes[i]
        cumPV += prices[i] * volumes[i]
        vwap[i] = cumPV / cumVol
    }
    return vwap[n-1]
}

// ---------- 场景 8：矩阵双重循环（1000 × 1000） ----------
def scenarioMatrixLoop(){
    n = 1000
    matrixValue = matrix(DOUBLE, n, n)
    for(i in 0..(n-1)){
        for(j in 0..(n-1)){
            matrixValue[i, j] = i * n + j
        }
    }
    result = 0.0
    for(i in 0..(n-1)){
        rowSum = 0.0
        for(j in 0..(n-1)){
            rowSum += matrixValue[i, j]
        }
        result += rowSum
    }
    return result
}

// ---------- 场景 9：逐条条件判断因子计算（50 万条） ----------
def scenarioConditionalFactor(){
    n = 500000
    prices = 50.0 + double((1..n) % 100)
    volumes = 1000 + (1..n) % 10000
    result = 0.0
    for(i in 0..(n-1)){
        if(prices[i] > 100.0){
            if(volumes[i] > 5000){
                result += prices[i] * volumes[i] * 0.001
            } else {
                result += prices[i] * volumes[i] * 0.0005
            }
        } else {
            result -= prices[i] * volumes[i] * 0.0001
        }
    }
    return result
}

// ---------- 场景 10：try-catch 循环（50 万次） ----------
def scenarioTryCatch(){
    n = 500000
    result = 0.0
    for(i in 0..(n-1)){
        try{
            result += i * 1.1
        }catch(ex){
            result += 0.0
        }
    }
    return result
}

// ---------- 场景 11：for 循环密集计算（100 万次） ----------
def scenarioDenseFor(){
    n = 1000000
    result = array(DOUBLE, n)
    for(i in 0..(n-1)){
        result[i] = i * 1.1 + sin(i)
    }
    return sum(result)
}

/*
 * 运行测试。
 * timer{} 输出该次执行的耗时；先执行的赋值语句用于保存并比对确定性结果。
 */
print("===== enableDynamicScriptOptimization 第五节性能测试开始 =====")
disableDynamicScriptOptimization()

print("\n[1/11] 调用链封装在函数体内（100 万次）")
offChain = scenarioChainInFunction()
timer{ scenarioChainInFunction() }
enableDynamicScriptOptimization()
onChain = scenarioChainInFunction()
checkSameResult("调用链封装在函数体内", offChain, onChain)
timer{ scenarioChainInFunction() }
disableDynamicScriptOptimization()

print("\n[2/11] 循环内并列调用 3 个函数（100 万次）")
offParallel = scenarioParallelFunctions()
timer{ scenarioParallelFunctions() }
enableDynamicScriptOptimization()
onParallel = scenarioParallelFunctions()
checkSameResult("循环内并列调用 3 个函数", offParallel, onParallel)
timer{ scenarioParallelFunctions() }
disableDynamicScriptOptimization()

print("\n[3/11] 单层自定义函数调用循环（100 万次）")
offSingle = scenarioSingleFunctionCall()
timer{ scenarioSingleFunctionCall() }
enableDynamicScriptOptimization()
onSingle = scenarioSingleFunctionCall()
checkSameResult("单层自定义函数调用循环", offSingle, onSingle)
timer{ scenarioSingleFunctionCall() }
disableDynamicScriptOptimization()

print("\n[4/11] lambda 表达式循环调用（100 万次）")
offLambda = scenarioLambdaCall()
timer{ scenarioLambdaCall() }
enableDynamicScriptOptimization()
onLambda = scenarioLambdaCall()
checkSameResult("lambda 表达式循环调用", offLambda, onLambda)
timer{ scenarioLambdaCall() }
disableDynamicScriptOptimization()

print("\n[5/11] do-while 循环（100 万次）")
offDoWhile = scenarioDoWhile()
timer{ scenarioDoWhile() }
enableDynamicScriptOptimization()
onDoWhile = scenarioDoWhile()
checkSameResult("do-while 循环", offDoWhile, onDoWhile)
timer{ scenarioDoWhile() }
disableDynamicScriptOptimization()

print("\n[6/11] while 循环（100 万次）")
offWhile = scenarioWhile()
timer{ scenarioWhile() }
enableDynamicScriptOptimization()
onWhile = scenarioWhile()
checkSameResult("while 循环", offWhile, onWhile)
timer{ scenarioWhile() }
disableDynamicScriptOptimization()

print("\n[7/11] VWAP 累计计算（50 万条）")
offVwap = scenarioVwap()
timer{ scenarioVwap() }
enableDynamicScriptOptimization()
onVwap = scenarioVwap()
checkSameResult("VWAP 累计计算", offVwap, onVwap)
timer{ scenarioVwap() }
disableDynamicScriptOptimization()

print("\n[8/11] 矩阵双重循环（1000 × 1000）")
offMatrix = scenarioMatrixLoop()
timer{ scenarioMatrixLoop() }
enableDynamicScriptOptimization()
onMatrix = scenarioMatrixLoop()
checkSameResult("矩阵双重循环", offMatrix, onMatrix)
timer{ scenarioMatrixLoop() }
disableDynamicScriptOptimization()

print("\n[9/11] 逐条条件判断因子计算（50 万条）")
offFactor = scenarioConditionalFactor()
timer{ scenarioConditionalFactor() }
enableDynamicScriptOptimization()
onFactor = scenarioConditionalFactor()
checkSameResult("逐条条件判断因子计算", offFactor, onFactor)
timer{ scenarioConditionalFactor() }
disableDynamicScriptOptimization()

print("\n[10/11] try-catch 循环（50 万次）")
offTryCatch = scenarioTryCatch()
timer{ scenarioTryCatch() }
enableDynamicScriptOptimization()
onTryCatch = scenarioTryCatch()
checkSameResult("try-catch 循环", offTryCatch, onTryCatch)
timer{ scenarioTryCatch() }
disableDynamicScriptOptimization()

print("\n[11/11] for 循环密集计算（100 万次）")
offDenseFor = scenarioDenseFor()
timer{ scenarioDenseFor() }
enableDynamicScriptOptimization()
onDenseFor = scenarioDenseFor()
checkSameResult("for 循环密集计算", offDenseFor, onDenseFor)
timer{ scenarioDenseFor() }

// 恢复当前会话为关闭状态。
disableDynamicScriptOptimization()
print("===== 全部 11 个场景执行完成，当前会话已关闭优化 =====")
