- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在做第一个生产 web 服务,所以我对这门语言和一些概念/模式还很陌生。
我的问题与处理程序有关,本质上是如何在不降低性能的情况下提取重复代码。
我遇到了包装 http.Handle
或 http.HandlerFunc
以清理代码的模式。例如这篇博文在这里使用适配器模式 https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.hvsc236iv
它可能会以这样的方式结束(从 blob 帖子中复制):
http.Handle("/", Adapt(indexHandler, AddHeader("Server", "Mine"),
CheckAuth(providers),
CopyMgoSession(db),
Notify(logger),
)
这基本上是一个深度嵌套的函数调用。
我的问题是堆栈中发生了什么以及服务的性能如何?使用此模式,每个用户请求都会向堆栈添加至少 5 个堆栈帧。当流量很高时,这是可以接受的还是会对性能产生负面影响?
最佳答案
链接中间件基本上只是让链的处理程序调用下一个,通常基于是否一切顺利的条件。或者在另一种方法中,一些外部机制可能会逐个调用处理程序。
但是,所有事情都归结为将调用处理程序。 Handler.ServeHTTP()
方法如下所示:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
一个带有 2 个参数且没有返回值的简单方法。参数类型为 http.ResponseWriter
(接口(interface)类型)和 *http.Request
(指针类型)。
因此,调用处理程序的 ServeHTTP()
涉及两件事:制作其参数的副本 - 因为它们很小,所以速度很快,并且实际进行调用(处理堆栈更新,例如创建一个新的堆栈框架,记录返回地址,保存使用过的寄存器,并执行被调用的函数)——这也非常快(参见答案末尾的引用)。
那么你应该担心调用函数吗?不。与包含所有内容的处理程序相比,这会降低性能吗?是的。差异显着吗?不会。为 HTTP 请求提供服务可能需要数百毫秒(包括网络延迟)。在您的处理程序中调用 10 个函数不会使其明显变慢。
如果您担心函数调用导致的性能损失,那么您的应用将包含一个 main()
函数。显然没有人想要那样。您创建函数将最初的大问题分解为较小的问题(递归地直到它“足够小”以独立存在),您可以监督和重用和< em>独立于其他人进行测试,然后您将您的大问题从较小的问题中组装出来。这实际上不是性能问题,而是可维护性 和可重用性。您真的要将检查用户身份的 100 行代码复制到所有 10 个不同的处理程序吗?
最后一件事。您是否应该担心“消耗”堆栈(导致堆栈溢出错误)?答案是不。一个 goroutine 以一个 4096 字节的小堆栈开始,它可以根据需要增长和收缩,而没有用完的风险。在 Why is a Goroutine’s stack infinite? 阅读更多相关信息也详见 FAQ: Why goroutines instead of threads?
To make the stacks small, Go's run-time uses resizable, bounded stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time grows (and shrinks) the memory for storing the stack automatically, allowing many goroutines to live in a modest amount of memory. The CPU overhead averages about three cheap instructions per function call.
关于performance - http.Handle wrapper pattern -> 堆栈会膨胀吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39869716/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!