duanjian5059 2014-03-26 00:53
浏览 273
已采纳

计算在Go中调用(请求处理程序)函数的次数

Context

I'm making a web app that serves dynamically generated pdfs. These contain content from the internet, so every time it serves a pdf, it downloads a number of files to a new temporary folder.

The Problem

I end up with a large number of folders after I load the page once, so it seems that, for some reason, the handler is being called multiple times, which is an issue because I'm downloading multiple times more than I need to of not insubstantial files. I'd like to check at what stage of the process multiple requests are occurring.

The Question

Is there a way of working out how many times a function has been called, quite possibly using closures? (I haven't quite got closures into my mental model for programming yet; I don't completely understand them/how they're used). This would preferably be something involving an int in the language rather than printing something at every stage and counting by hand - I'm looking for a more scalable solution than that (for later situations as well as this one).

Thanks!

  • 写回答

2条回答 默认 最新

  • du3669 2014-03-26 01:10
    关注

    Here are two ways you can count function calls, and one for method calls. There are plenty of other ways too, but just to get you started:

    Using closure: (not what I would recommended)

    package main

    import(
        "fmt"
        "sync/atomic"
    )
    
    var Foo = func() (func() uint64) {
        var called uint64
        return func() uint64 {
            atomic.AddUint64(&called, 1)
            fmt.Println("Foo!")
            return called
        }
    }()
    
    func main() {
        Foo()
        c := Foo()
        fmt.Printf("Foo() is called %d times
    ", c)
    }
    

    Playground: http://play.golang.org/p/euKbamdI7h

    Using global counter:

    package main
    
    import (
        "fmt"
        "sync/atomic"
    )
    
    var called uint64
    
    func Foo() {
        atomic.AddUint64(&called, 1)
        fmt.Println("Foo!");
    }
    
    func main() {
        Foo()
        Foo()
        fmt.Printf("Foo() is called %d times
    ", called)
    }
    

    Playground: http://play.golang.org/p/3Ib29VCnoF

    Counting method calls:

    package main
    
    import (
        "fmt"
        "sync/atomic"
    )
    
    type T struct {
        Called uint64
    }
    
    func (t *T) Foo() {
        atomic.AddUint64(&t.Called, 1)
        fmt.Println("Foo!")
    }
    
    func main() {
        var obj T
        obj.Foo()
        obj.Foo()
        fmt.Printf("obj.Foo() is called %d times
    ", obj.Called)
    }
    

    Playground: http://play.golang.org/p/59eOQdUQU1

    Edit:

    I just realized that the handler might not be in your own package. In such a case, you might want to write a wrapper:

    var called uint64
    
    func Foo() {
        atomic.AddUint64(&called, 1)
        importedPackage.Foo()
    }
    

    Edit 2:

    Updated the examples to use atomic +1 operations.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动