- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我必须找到非常大的数组的最大值和最小值。为此,我正在使用
Math.max.apply(Math, my_array);
Math.min.apply(Math, my_array);
它在 Firefox 和 IE 上运行良好,但在 Chrome 上我总是得到 Maximum call stack size exceeded
错误...我当前的数组有 221954 个元素,这不是我最大的。
有人知道如何在 Chrome 上解决这个错误吗?如何优化最大值和最小值的搜索?
对于那些不相信的人,请在 Chrome 的控制台中尝试:
var xxx = []
for(var i=0; i<300000; i++){
xxx.push(Math.random());
}
Math.max.apply(Math, xxx);
---> RangeError:超出最大调用堆栈大小
最佳答案
这个问题与 Math.max 和 Math.min 无关。
Function.prototype.apply 只能接收有限长度的数组作为它的第二个参数。
在本地,我使用以下方法在 Chrome 中对其进行了测试:
function limit(l) {
var x = []; x.length = l;
(function (){}).apply(null, x);
}
在本地,limit(l) 在 l = 124980 时崩溃。在 canary 中,这是另一个数字,但也是 ~125k。
这是为什么会发生这种情况的示例解释:https://code.google.com/p/v8/issues/detail?id=2896 (它在其他 JS 引擎中也是可重现的,例如 MDN 提到了这个问题:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Using_apply_and_built-in_functions(以“但要小心......”开头),指向 WebKit bugzilla 中的这个问题:https://bugs.webkit.org/show_bug.cgi?id=80797)。据我了解为什么在 V8 中抛出 RangeError:
V8 在汇编中实现了 Function.prototype.apply。在调用函数之前,它应该放置所有函数调用参数,例如thisArg 和第二个 arg 数组的所有成员,一个接一个,在调用 javascript 函数之前压入堆栈。但是堆栈的容量是有限的,如果你达到了限制,你会得到 RangeError。
这是我在 V8 源代码中找到的(IA-32 程序集,builtins-ia32.cc):
void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
static const int kArgumentsOffset = 2 * kPointerSize;
static const int kReceiverOffset = 3 * kPointerSize;
static const int kFunctionOffset = 4 * kPointerSize;
{
FrameScope frame_scope(masm, StackFrame::INTERNAL);
__ push(Operand(ebp, kFunctionOffset)); // push this
__ push(Operand(ebp, kArgumentsOffset)); // push arguments
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
Label okay;
ExternalReference real_stack_limit =
ExternalReference::address_of_real_stack_limit(masm->isolate());
__ mov(edi, Operand::StaticVariable(real_stack_limit));
// Make ecx the space we have left. The stack might already be overflowed
// here which will cause ecx to become negative.
// !! ADDED COMMENT: IA-32 stack grows downwards, if address to its current top is 0 then it cannot be placed any more elements into. esp is the pointer to stack top.
__ mov(ecx, esp);
// !! ADDED COMMENT: edi holds the "real_stack_limit", which holds the minimum address that stack should not grow beyond. If we subtract edi from ecx (=esp, or, in other words, "how much space is left on the stack"), we may get a negative value, and the comment above says that
__ sub(ecx, edi);
// Make edx the space we need for the array when it is unrolled onto the
// stack.
// !! ADDED COMMENT: eax holds the number of arguments for this apply call, where every member of the 2nd argument array counts as separate argument
__ mov(edx, eax);
// !! ADDED COMMENT: kPointerSizeLog2 - kSmiTagSize is the base-2-logarithm of how much space would 1 argument take. By shl we in fact get 2^(kPointerSizeLog2 - kSmiTagSize) * arguments_count, i.e. how much space do actual arguments occupy
__ shl(edx, kPointerSizeLog2 - kSmiTagSize);
// Check if the arguments will overflow the stack.
// !! ADDED COMMENT: we compare ecx which is how much data we can put onto stack with edx which now means how much data we need to put onto stack
__ cmp(ecx, edx);
__ j(greater, &okay); // Signed comparison.
// Out of stack space.
__ push(Operand(ebp, 4 * kPointerSize)); // push this
__ push(eax);
__ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
请检查!!添加评论以解释我是如何理解它的。
这是用 JS 编写的 APPLY_OVERFLOW 函数(同样,V8 源代码,runtime.js):
function APPLY_OVERFLOW(length) {
throw %MakeRangeError('stack_overflow', []);
}
编辑:在你的情况下,我会这样:
var max = -Infinity;
for(var i = 0; i < arr.length; i++ ) if (arr[i] > max) max = arr[i];
关于javascript - Chrome : How to solve "Maximum call stack size exceeded" errors on Math. max.apply(数学,数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18308700/
快速且可能简单的 Lambda 问题: 我有一家有评论的餐厅。我想查询具有以下内容的那个: 最大(平均评分) 和 Max(ReviewCount) 和 Max(NewestReviewDate) 和
在尝试使用 C++17 折叠表达式时,我尝试实现 max sizeof ,其中结果是类型 sizeof 的最大值。我有一个使用变量和 lambda 的丑陋折叠版本,但我想不出一种使用折叠表达式和 st
我目前正在使用 C 并遇到了一些我觉得有趣的东西,但似乎在这里找不到任何类似的东西。 我正在为数组(大小 1000000)静态分配内存。我知道这相当大并且有可能引起问题。但是,使用 10^6 不会出现
我有一个具有 max-height 的 div 和其中的图像,应该使用 max-width:100% 和 max-height:100%。在 Chromium 中,这是可行的,但 Firefox 仅使
我有一个最大高度的 div 和里面的一个图像,它应该使用最大宽度:100% 和最大高度:100%。在 Chromium 中,这是可行的,但 Firefox 仅使用最大宽度而忽略最大高度。 div#ov
在一本在线 awk 手册中我找到了例子awk '{ if (NF > max) max = NF } END { print max }' 该程序打印任何输入行上的最大字段数。但我不明白 awk 如何
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在制作一个非循环图数据库。 表 Material (id_item,id_collection,...)主键(id_item,id_collection) (item可以是collection本身
我有以下两个表。 1.电影详情(电影ID、电影名称、评分、票数、年份) 2.电影类型(Movie-ID,Genre) 我正在使用以下查询来执行连接并获得每个评分最高的电影流派。 select Movi
我有一个查询,我想返回 idevent 中给定传感器 ID (sensorID) 范围内的最高 ID 值,但是查询没有返回最高值。 我运行查询时减去 max() 语句的结果: mysql> SELEC
SUM(MAX() + MAX()) 有正确的方法吗? 这是我一直在努力做的事情 SELECT SUM(MAX(account.BALANCE1) + MAX(account.BALANCE2))
这个问题类似于CSS media queries: max-width OR max-height , 但由于我的代表不够高,我无法在回复中添加评论(问题),我想在原始问题中添加。 与其他主题中的发帖
Jon Skeet今天报告(source): Math.Max(1f, float.NaN) == NaN new[] { 1f, float.NaN }.Max() == 1f 为什么? 编辑:双倍
这个问题已经有答案了: Java 8 stream's .min() and .max(): why does this compile? (5 个回答) 已关闭 7 年前。 我正在学习1z0-809
我在处理一些数据库记录时遇到了一些挑战。 我需要为特定列获取具有 MAX 值的行,并且这些记录必须介于两个时间戳值之间。 这是SQL查询 SELECT id, MAX(amount), created
我想在媒体查询中使用 AND 条件。我使用了下面的代码,但是没有用 @media screen and (max-width: 995px AND max-height: 700px) { } 最佳答
在编写 CSS 媒体查询时,有什么方法可以用“或”逻辑指定多个条件吗? 我正在尝试做这样的事情: /* This doesn't work */ @media screen and (max-widt
我对仅使用 max(list array) 和 np.max(list array) 之间的区别有疑问。 这里唯一的区别是 Python 返回代码所需的时间吗? 最佳答案 它们在边缘情况下可能不同,例
例如: a = [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.
这个问题在这里已经有了答案: Java 8 stream's .min() and .max(): why does this compile? (5 个答案) 关闭 6 年前。 我正在学习 1z0
我是一名优秀的程序员,十分优秀!