jjzjj

go - 在 Go 中测量 FLOPS

coder 2023-06-26 原文

我想编写一个 go 程序来对我的 CPU 进行基准测试并计算出我的笔记本电脑的 GFLOPS。

func benchmarkFlopTime(){
    num_operations := int(100000000)
    var timeArray[] time.Duration;

    var result float64
    for i:=0; i < num_operations; i++ {
        t1 := time.Now()
        result = 1.0 + 312.232
        elapsed := time.Since(t1)
        timeArray = append(timeArray, elapsed)
        result += 1.0
    }

    fmt.Println("Result (ns):", float64(sumTimeArray(timeArray))/float64(time.Duration(num_operations)))
}

Ouput1: Result (ns): 9.99604753ns

解释:

这段代码给我大约 0.1 GFLOPS ((1sec/10ns)/10^-9)。我知道我的 CPU 每个周期可以执行 8 次操作,而我只执行一次,所以我可以得到一个因子 8,假设我有 1GFLOPS

问题:

  • 不过,我的 2.5GHZ i7、8 核笔记本电脑的理论 GFLOPS 数应该是:8*2.5*8 = 160GFLOPS。我远远低于这个结果。

我明确表示在编译 go install -gcflags '-N -l' github.com/golang/cpu-benchmark 时我没有激活优化。

我们能解释这个远低于理论值的值吗? Go 可以衡量吗?

最佳答案

这是一个(简单的)Go 基准测试,它对一个循环和二十个浮点运算进行计时。

package main

import (
    "fmt"
    "math"
    "runtime"
    "testing"
    "time"
)

var (
    f  float64
    e  float64 = math.E
    pi float64 = math.Pi
)

const nFlop = 20 // benchmarkFloatOps

func benchmarkFloatOps(n int) {
    for i := 0; i < n; i++ {
        f = pi + e
        f = pi - e
        f = pi * e
        f = pi / e
        f = pi + e
        f = pi - e
        f = pi * e
        f = pi / e
        f = pi + e
        f = pi - e
        f = pi * e
        f = pi / e
        f = pi + e
        f = pi - e
        f = pi * e
        f = pi / e
        f = pi + e
        f = pi - e
        f = pi * e
        f = pi / e
    }
}

func BenchmarkFloatOps(b *testing.B) {
    benchmarkFloatOps(b.N)
}

func Results(t time.Duration, n int, nFlop int) {
    fmt.Println(
        t, nFlop*n, "ops",
        float64(t)/float64(time.Duration((nFlop*n))), "ns/op",
    )
}

func main() {
    runtime.GOMAXPROCS(1)

    // testing benchmark
    br := testing.Benchmark(BenchmarkFloatOps)
    Results(br.T, br.N, nFlop)

    // manual benchmark
    n := br.N
    start := time.Now()
    benchmarkFloatOps(n)
    end := time.Now()
    elapsed := end.Sub(start)
    Results(elapsed, n, nFlop)
}

输出:Intel i7-6700 CPU 3.40GHz:

1.296967371s 4000000000 ops 0.32424184275 ns/op
1.299078813s 4000000000 ops 0.32476970325 ns/op

benchmarkFloatOps 的伪代码:

$ go tool compile -S flops.go

"".benchmarkFloatOps t=1 size=592 value=0 args=0x8 locals=0x0
    0x0000 00000 (flops.go:19)  TEXT    "".benchmarkFloatOps(SB), $0-8
    0x0000 00000 (flops.go:19)  NOP
    0x0000 00000 (flops.go:19)  NOP
    0x0000 00000 (flops.go:19)  MOVQ    "".n+8(FP), CX
    0x0005 00005 (flops.go:19)  FUNCDATA    $0, gclocals·5184031d3a32a42d85027f073f873668(SB)
    0x0005 00005 (flops.go:19)  FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x0005 00005 (flops.go:20)  MOVQ    $0, AX
    0x0007 00007 (flops.go:20)  CMPQ    AX, CX
    0x000a 00010 (flops.go:20)  JGE $0, 588
    0x0010 00016 (flops.go:21)  MOVSD   "".pi(SB), X0
    0x0018 00024 (flops.go:21)  MOVSD   "".e(SB), X1
    0x0020 00032 (flops.go:21)  ADDSD   X1, X0
    0x0024 00036 (flops.go:21)  MOVSD   X0, "".f(SB)
    0x002c 00044 (flops.go:22)  MOVSD   "".pi(SB), X0
    0x0034 00052 (flops.go:22)  MOVSD   "".e(SB), X1
    0x003c 00060 (flops.go:22)  SUBSD   X1, X0
    0x0040 00064 (flops.go:22)  MOVSD   X0, "".f(SB)
    0x0048 00072 (flops.go:23)  MOVSD   "".pi(SB), X0
    0x0050 00080 (flops.go:23)  MOVSD   "".e(SB), X1
    0x0058 00088 (flops.go:23)  MULSD   X1, X0
    0x005c 00092 (flops.go:23)  MOVSD   X0, "".f(SB)
    0x0064 00100 (flops.go:24)  MOVSD   "".pi(SB), X0
    0x006c 00108 (flops.go:24)  MOVSD   "".e(SB), X1
    0x0074 00116 (flops.go:24)  DIVSD   X1, X0
    0x0078 00120 (flops.go:24)  MOVSD   X0, "".f(SB)
    0x0080 00128 (flops.go:25)  MOVSD   "".pi(SB), X0
    0x0088 00136 (flops.go:25)  MOVSD   "".e(SB), X1
    0x0090 00144 (flops.go:25)  ADDSD   X1, X0
    0x0094 00148 (flops.go:25)  MOVSD   X0, "".f(SB)
    0x009c 00156 (flops.go:26)  MOVSD   "".pi(SB), X0
    0x00a4 00164 (flops.go:26)  MOVSD   "".e(SB), X1
    0x00ac 00172 (flops.go:26)  SUBSD   X1, X0
    0x00b0 00176 (flops.go:26)  MOVSD   X0, "".f(SB)
    0x00b8 00184 (flops.go:27)  MOVSD   "".pi(SB), X0
    0x00c0 00192 (flops.go:27)  MOVSD   "".e(SB), X1
    0x00c8 00200 (flops.go:27)  MULSD   X1, X0
    0x00cc 00204 (flops.go:27)  MOVSD   X0, "".f(SB)
    0x00d4 00212 (flops.go:28)  MOVSD   "".pi(SB), X0
    0x00dc 00220 (flops.go:28)  MOVSD   "".e(SB), X1
    0x00e4 00228 (flops.go:28)  DIVSD   X1, X0
    0x00e8 00232 (flops.go:28)  MOVSD   X0, "".f(SB)
    0x00f0 00240 (flops.go:29)  MOVSD   "".pi(SB), X0
    0x00f8 00248 (flops.go:29)  MOVSD   "".e(SB), X1
    0x0100 00256 (flops.go:29)  ADDSD   X1, X0
    0x0104 00260 (flops.go:29)  MOVSD   X0, "".f(SB)
    0x010c 00268 (flops.go:30)  MOVSD   "".pi(SB), X0
    0x0114 00276 (flops.go:30)  MOVSD   "".e(SB), X1
    0x011c 00284 (flops.go:30)  SUBSD   X1, X0
    0x0120 00288 (flops.go:30)  MOVSD   X0, "".f(SB)
    0x0128 00296 (flops.go:31)  MOVSD   "".pi(SB), X0
    0x0130 00304 (flops.go:31)  MOVSD   "".e(SB), X1
    0x0138 00312 (flops.go:31)  MULSD   X1, X0
    0x013c 00316 (flops.go:31)  MOVSD   X0, "".f(SB)
    0x0144 00324 (flops.go:32)  MOVSD   "".pi(SB), X0
    0x014c 00332 (flops.go:32)  MOVSD   "".e(SB), X1
    0x0154 00340 (flops.go:32)  DIVSD   X1, X0
    0x0158 00344 (flops.go:32)  MOVSD   X0, "".f(SB)
    0x0160 00352 (flops.go:33)  MOVSD   "".pi(SB), X0
    0x0168 00360 (flops.go:33)  MOVSD   "".e(SB), X1
    0x0170 00368 (flops.go:33)  ADDSD   X1, X0
    0x0174 00372 (flops.go:33)  MOVSD   X0, "".f(SB)
    0x017c 00380 (flops.go:34)  MOVSD   "".pi(SB), X0
    0x0184 00388 (flops.go:34)  MOVSD   "".e(SB), X1
    0x018c 00396 (flops.go:34)  SUBSD   X1, X0
    0x0190 00400 (flops.go:34)  MOVSD   X0, "".f(SB)
    0x0198 00408 (flops.go:35)  MOVSD   "".pi(SB), X0
    0x01a0 00416 (flops.go:35)  MOVSD   "".e(SB), X1
    0x01a8 00424 (flops.go:35)  MULSD   X1, X0
    0x01ac 00428 (flops.go:35)  MOVSD   X0, "".f(SB)
    0x01b4 00436 (flops.go:36)  MOVSD   "".pi(SB), X0
    0x01bc 00444 (flops.go:36)  MOVSD   "".e(SB), X1
    0x01c4 00452 (flops.go:36)  DIVSD   X1, X0
    0x01c8 00456 (flops.go:36)  MOVSD   X0, "".f(SB)
    0x01d0 00464 (flops.go:37)  MOVSD   "".pi(SB), X0
    0x01d8 00472 (flops.go:37)  MOVSD   "".e(SB), X1
    0x01e0 00480 (flops.go:37)  ADDSD   X1, X0
    0x01e4 00484 (flops.go:37)  MOVSD   X0, "".f(SB)
    0x01ec 00492 (flops.go:38)  MOVSD   "".pi(SB), X0
    0x01f4 00500 (flops.go:38)  MOVSD   "".e(SB), X1
    0x01fc 00508 (flops.go:38)  SUBSD   X1, X0
    0x0200 00512 (flops.go:38)  MOVSD   X0, "".f(SB)
    0x0208 00520 (flops.go:39)  MOVSD   "".pi(SB), X0
    0x0210 00528 (flops.go:39)  MOVSD   "".e(SB), X1
    0x0218 00536 (flops.go:39)  MULSD   X1, X0
    0x021c 00540 (flops.go:39)  MOVSD   X0, "".f(SB)
    0x0224 00548 (flops.go:40)  MOVSD   "".pi(SB), X0
    0x022c 00556 (flops.go:40)  MOVSD   "".e(SB), X1
    0x0234 00564 (flops.go:40)  DIVSD   X1, X0
    0x0238 00568 (flops.go:40)  MOVSD   X0, "".f(SB)
    0x0240 00576 (flops.go:20)  INCQ    AX
    0x0243 00579 (flops.go:20)  NOP
    0x0243 00579 (flops.go:20)  CMPQ    AX, CX
    0x0246 00582 (flops.go:20)  JLT $0, 16
    0x024c 00588 (flops.go:42)  RET

benchmarkFloatOps 的目标代码:

$ go build flops.go && go tool objdump -s benchmarkFloatOps ./flops

TEXT main.benchmarkFloatOps(SB) /home/peter/Dropbox/gopath/src/so/benchmark/flops.go
    flops.go:19 0x401000    488b4c2408      MOVQ 0x8(SP), CX
    flops.go:20 0x401005    31c0            XORL AX, AX
    flops.go:20 0x401007    4839c8          CMPQ CX, AX
    flops.go:20 0x40100a    0f8d3c020000        JGE 0x40124c
    flops.go:21 0x401010    f20f1005e8801b00    REPNE MOVSD_XMM 0x1b80e8(IP), X0
    flops.go:21 0x401018    f20f100dd8801b00    REPNE MOVSD_XMM 0x1b80d8(IP), X1
    flops.go:21 0x401020    f20f58c1        REPNE ADDSD X1, X0
    flops.go:21 0x401024    f20f110544451e00    REPNE MOVSD_XMM X0, 0x1e4544(IP)
    flops.go:22 0x40102c    f20f1005cc801b00    REPNE MOVSD_XMM 0x1b80cc(IP), X0
    flops.go:22 0x401034    f20f100dbc801b00    REPNE MOVSD_XMM 0x1b80bc(IP), X1
    flops.go:22 0x40103c    f20f5cc1        REPNE SUBSD X1, X0
    flops.go:22 0x401040    f20f110528451e00    REPNE MOVSD_XMM X0, 0x1e4528(IP)
    flops.go:23 0x401048    f20f1005b0801b00    REPNE MOVSD_XMM 0x1b80b0(IP), X0
    flops.go:23 0x401050    f20f100da0801b00    REPNE MOVSD_XMM 0x1b80a0(IP), X1
    flops.go:23 0x401058    f20f59c1        REPNE MULSD X1, X0
    flops.go:23 0x40105c    f20f11050c451e00    REPNE MOVSD_XMM X0, 0x1e450c(IP)
    flops.go:24 0x401064    f20f100594801b00    REPNE MOVSD_XMM 0x1b8094(IP), X0
    flops.go:24 0x40106c    f20f100d84801b00    REPNE MOVSD_XMM 0x1b8084(IP), X1
    flops.go:24 0x401074    f20f5ec1        REPNE DIVSD X1, X0
    flops.go:24 0x401078    f20f1105f0441e00    REPNE MOVSD_XMM X0, 0x1e44f0(IP)
    flops.go:25 0x401080    f20f100578801b00    REPNE MOVSD_XMM 0x1b8078(IP), X0
    flops.go:25 0x401088    f20f100d68801b00    REPNE MOVSD_XMM 0x1b8068(IP), X1
    flops.go:25 0x401090    f20f58c1        REPNE ADDSD X1, X0
    flops.go:25 0x401094    f20f1105d4441e00    REPNE MOVSD_XMM X0, 0x1e44d4(IP)
    flops.go:26 0x40109c    f20f10055c801b00    REPNE MOVSD_XMM 0x1b805c(IP), X0
    flops.go:26 0x4010a4    f20f100d4c801b00    REPNE MOVSD_XMM 0x1b804c(IP), X1
    flops.go:26 0x4010ac    f20f5cc1        REPNE SUBSD X1, X0
    flops.go:26 0x4010b0    f20f1105b8441e00    REPNE MOVSD_XMM X0, 0x1e44b8(IP)
    flops.go:27 0x4010b8    f20f100540801b00    REPNE MOVSD_XMM 0x1b8040(IP), X0
    flops.go:27 0x4010c0    f20f100d30801b00    REPNE MOVSD_XMM 0x1b8030(IP), X1
    flops.go:27 0x4010c8    f20f59c1        REPNE MULSD X1, X0
    flops.go:27 0x4010cc    f20f11059c441e00    REPNE MOVSD_XMM X0, 0x1e449c(IP)
    flops.go:28 0x4010d4    f20f100524801b00    REPNE MOVSD_XMM 0x1b8024(IP), X0
    flops.go:28 0x4010dc    f20f100d14801b00    REPNE MOVSD_XMM 0x1b8014(IP), X1
    flops.go:28 0x4010e4    f20f5ec1        REPNE DIVSD X1, X0
    flops.go:28 0x4010e8    f20f110580441e00    REPNE MOVSD_XMM X0, 0x1e4480(IP)
    flops.go:29 0x4010f0    f20f100508801b00    REPNE MOVSD_XMM 0x1b8008(IP), X0
    flops.go:29 0x4010f8    f20f100df87f1b00    REPNE MOVSD_XMM 0x1b7ff8(IP), X1
    flops.go:29 0x401100    f20f58c1        REPNE ADDSD X1, X0
    flops.go:29 0x401104    f20f110564441e00    REPNE MOVSD_XMM X0, 0x1e4464(IP)
    flops.go:30 0x40110c    f20f1005ec7f1b00    REPNE MOVSD_XMM 0x1b7fec(IP), X0
    flops.go:30 0x401114    f20f100ddc7f1b00    REPNE MOVSD_XMM 0x1b7fdc(IP), X1
    flops.go:30 0x40111c    f20f5cc1        REPNE SUBSD X1, X0
    flops.go:30 0x401120    f20f110548441e00    REPNE MOVSD_XMM X0, 0x1e4448(IP)
    flops.go:31 0x401128    f20f1005d07f1b00    REPNE MOVSD_XMM 0x1b7fd0(IP), X0
    flops.go:31 0x401130    f20f100dc07f1b00    REPNE MOVSD_XMM 0x1b7fc0(IP), X1
    flops.go:31 0x401138    f20f59c1        REPNE MULSD X1, X0
    flops.go:31 0x40113c    f20f11052c441e00    REPNE MOVSD_XMM X0, 0x1e442c(IP)
    flops.go:32 0x401144    f20f1005b47f1b00    REPNE MOVSD_XMM 0x1b7fb4(IP), X0
    flops.go:32 0x40114c    f20f100da47f1b00    REPNE MOVSD_XMM 0x1b7fa4(IP), X1
    flops.go:32 0x401154    f20f5ec1        REPNE DIVSD X1, X0
    flops.go:32 0x401158    f20f110510441e00    REPNE MOVSD_XMM X0, 0x1e4410(IP)
    flops.go:33 0x401160    f20f1005987f1b00    REPNE MOVSD_XMM 0x1b7f98(IP), X0
    flops.go:33 0x401168    f20f100d887f1b00    REPNE MOVSD_XMM 0x1b7f88(IP), X1
    flops.go:33 0x401170    f20f58c1        REPNE ADDSD X1, X0
    flops.go:33 0x401174    f20f1105f4431e00    REPNE MOVSD_XMM X0, 0x1e43f4(IP)
    flops.go:34 0x40117c    f20f10057c7f1b00    REPNE MOVSD_XMM 0x1b7f7c(IP), X0
    flops.go:34 0x401184    f20f100d6c7f1b00    REPNE MOVSD_XMM 0x1b7f6c(IP), X1
    flops.go:34 0x40118c    f20f5cc1        REPNE SUBSD X1, X0
    flops.go:34 0x401190    f20f1105d8431e00    REPNE MOVSD_XMM X0, 0x1e43d8(IP)
    flops.go:35 0x401198    f20f1005607f1b00    REPNE MOVSD_XMM 0x1b7f60(IP), X0
    flops.go:35 0x4011a0    f20f100d507f1b00    REPNE MOVSD_XMM 0x1b7f50(IP), X1
    flops.go:35 0x4011a8    f20f59c1        REPNE MULSD X1, X0
    flops.go:35 0x4011ac    f20f1105bc431e00    REPNE MOVSD_XMM X0, 0x1e43bc(IP)
    flops.go:36 0x4011b4    f20f1005447f1b00    REPNE MOVSD_XMM 0x1b7f44(IP), X0
    flops.go:36 0x4011bc    f20f100d347f1b00    REPNE MOVSD_XMM 0x1b7f34(IP), X1
    flops.go:36 0x4011c4    f20f5ec1        REPNE DIVSD X1, X0
    flops.go:36 0x4011c8    f20f1105a0431e00    REPNE MOVSD_XMM X0, 0x1e43a0(IP)
    flops.go:37 0x4011d0    f20f1005287f1b00    REPNE MOVSD_XMM 0x1b7f28(IP), X0
    flops.go:37 0x4011d8    f20f100d187f1b00    REPNE MOVSD_XMM 0x1b7f18(IP), X1
    flops.go:37 0x4011e0    f20f58c1        REPNE ADDSD X1, X0
    flops.go:37 0x4011e4    f20f110584431e00    REPNE MOVSD_XMM X0, 0x1e4384(IP)
    flops.go:38 0x4011ec    f20f10050c7f1b00    REPNE MOVSD_XMM 0x1b7f0c(IP), X0
    flops.go:38 0x4011f4    f20f100dfc7e1b00    REPNE MOVSD_XMM 0x1b7efc(IP), X1
    flops.go:38 0x4011fc    f20f5cc1        REPNE SUBSD X1, X0
    flops.go:38 0x401200    f20f110568431e00    REPNE MOVSD_XMM X0, 0x1e4368(IP)
    flops.go:39 0x401208    f20f1005f07e1b00    REPNE MOVSD_XMM 0x1b7ef0(IP), X0
    flops.go:39 0x401210    f20f100de07e1b00    REPNE MOVSD_XMM 0x1b7ee0(IP), X1
    flops.go:39 0x401218    f20f59c1        REPNE MULSD X1, X0
    flops.go:39 0x40121c    f20f11054c431e00    REPNE MOVSD_XMM X0, 0x1e434c(IP)
    flops.go:40 0x401224    f20f1005d47e1b00    REPNE MOVSD_XMM 0x1b7ed4(IP), X0
    flops.go:40 0x40122c    f20f100dc47e1b00    REPNE MOVSD_XMM 0x1b7ec4(IP), X1
    flops.go:40 0x401234    f20f5ec1        REPNE DIVSD X1, X0
    flops.go:40 0x401238    f20f110530431e00    REPNE MOVSD_XMM X0, 0x1e4330(IP)
    flops.go:20 0x401240    48ffc0          INCQ AX
    flops.go:20 0x401243    4839c8          CMPQ CX, AX
    flops.go:20 0x401246    0f8cc4fdffff        JL 0x401010
    flops.go:42 0x40124c    c3          RET

关于go - 在 Go 中测量 FLOPS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35162611/

有关go - 在 Go 中测量 FLOPS的更多相关文章

  1. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  2. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  3. ruby - 如何从 Sass 混合方程中删除测量单位? - 2

    我编写了一个非常简单的Sassmixin,用于将像素值转换为rem值(请参阅JonathanSnook的articleonthebenefitsofusingrems)。这是代码://MixinCode$base_font_size:10;//10px@mixinrem($key,$px){#{$key}:#{$px}px;#{$key}:#{$px/$base_font_size}rem;}//Includesyntaxp{@includerem(font-size,14);}//RenderedCSSp{font-size:14px;font-size:1.4rem;}这个mixi

  4. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  5. ruby - 如何测量 cucumber 步骤的执行时间 - 2

    我正在寻找一种方法来衡量我的cucumber步骤的执行时间。使用junit格式,我设法获得了一些有关功能和场景执行时间的数据,但我还想查看场景中步骤的时间。 最佳答案 cucumber--formatusage“打印使用步骤定义的地方。首先列出最慢的步骤定义(带有持续时间)。” 关于ruby-如何测量cucumber步骤的执行时间,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7

  6. ruby-on-rails - Rails 上的 ruby : How to have multiple submit buttons going to different methods (maybe with with_action? ) - 2

    这个问题在这里已经有了答案:HowdoIcreatemultiplesubmitbuttonsforthesameforminRails?(7个答案)关闭9年前。所以..'save'%>'library'%>然后在我的Controller中:with_actiondo|a|a.savedoenda.librarydoendend问题是只有一个操作被调用...两个submit_tags调用相同的操作...知道为什么吗?或者我如何获得两个按钮以将表单提交给两种不同的方法?

  7. ruby - 使用 Ruby 测量 HTTP 请求的响应时间 - 2

    我正在构建一个供个人使用的小型网站,以测试我公司制作的API。我的老板想要一个网站,我们可以在其中输入网站,使用GET或POST请求表单,以及发送请求的次数。他想要记录请求、每个请求的时间以及所有请求的平均时间。有没有一种方法可以使用Ruby测量GET或POST请求的响应时间?我查看了Net::HTTP库,但没有看到任何返回所用时间的内容。有没有网站已经这样做了?他们需要有一个GUI,这样非技术人员也可以使用它。如果没有,我计划使用一个简单的表单来运行脚本,将该脚本的输出写入文本文件或电子表格,然后将其发送给用户。还有其他建议吗?(一个漂亮的AJAX外观界面可能工作得很好,但可能需要数

  8. ruby - 测量命令行调用的执行时间 - 2

    我正在编写一个Ruby1.9.2脚本来评估不同外部命令行调用的执行时间。我使用ruby​​Process.system方法来执行命令行调用并trycatch执行时间如下:start=Time.nowsystem("./script1","argX")puts"Duration:#{Time.now-start}seconds"现在我遇到的问题是,持续时间反射(reflect)的不是外部进程的执行时间,而是“系统”调用的执行时间。知道如何测量外部进程的执行时间吗? 最佳答案 好的。如果我明白你想做什么,你想计算“./script1”调

  9. DiFi: A Go-as-You-Pay Wi-Fi Access System 精读笔记(三) - 2

    IV.SYSTEMIMPLEMENTATIONWeadoptmodulardesignfollowingtheintegrationofblockchain.Itbringsmoreflexibilitybyseparatingtheimplementationofdifferentfunctionalities,sowecouldleveragetheadvantagesoftheblockchain-basedsmartcontractwhilereducingoverhead.Figure3illustrateshowdifferentmodulesareinvolvedintheint

  10. go-templates - 如何根据表达式有条件地在 Go 模板中设置变量,如果不使用 if 语句包装可能会导致错误 - 2

    问题我该如何做这样的事情:{{$use_ssl:=(ne$.Env.CERT_NAME"")}}其中$.Env.CERT_NAME可能为零/未定义。如果它是零,它给出这个错误:at:errorcallingne:invalidtypeforcomparison注意:我无法控制传递给Go模板的对象,因此必须完全在模板本身内解决这个问题。我尝试过的我试图通过首先检查它是否为非空来变通:{{$use_ssl:=(($.Env.CERT_NAME)&&(ne$.Env.CERT_NAME""))}}但它给出了这个错误:unexpected"&"inoperand所以我切换到这个,这在语法上是允

随机推荐