JS性能提示的多个来源鼓励开发人员减少"范围链查找".例如,当您访问全局变量时,IIFE被吹捧为具有"减少范围链查找" 的额外好处.这听起来很合乎逻辑,甚至可能被视为理所当然,所以我没有质疑智慧.像许多其他人一样,我一直很高兴地使用IIFE认为除了避免全局命名空间污染之外,还会比任何全球代码都提升性能.
我们今天的期望:
(function($, window, undefined) {
// apparently, variable access here is faster than outside the IIFE
})(jQuery, window);
Run Code Online (Sandbox Code Playgroud)
人们会期望:将这简化/扩展到一般情况:
var x = 0;
(function(window) {
// accessing window.x here should be faster
})(window);
Run Code Online (Sandbox Code Playgroud)
根据我对JS的理解,全球范围内x = 1;和之间没有区别window.x = 1;.因此,期望它们具有同等性能是合乎逻辑的,对吧?错误.我进行了一些测试,发现访问时间存在显着差异.
好吧,也许如果我将window.x = 1;内部放置在IIFE中,它应该运行得更快(即使只是略微),对吧?又错了.
好吧,也许是Firefox; 让我们试试Chrome吧(V8是JS速度的基准,是吗?)它应该击败Firefox以获取直接访问全局变量等简单的东西,对吧?又错了.
因此,我开始在两个浏览器的每一个中确切地找出哪种访问方法最快.所以我们假设我们从一行代码开始:var x = 0;.在x声明(并愉快地附加window)之后,这些访问方法中哪一个会最快,为什么?
直接在全球范围内
x = x + 1;
Run Code Online (Sandbox Code Playgroud)直接在全球范围内,但前缀为 window
window.x = window.x + …Run Code Online (Sandbox Code Playgroud)在ES6中,iterable是一个允许的对象for... of,并且具有Symbol.iterator键.
数组是可迭代的,就像集合和地图一样.问题是:HTMLCollection和NodeList是否可迭代?他们应该是吗?
MDN文档似乎暗示a NodeList是可迭代的.
for...of循环将在支持的浏览器for...of(如Firefox 13及更高版本)中正确循环NodeList对象
这似乎证实了Firefox的行为.
我在Chrome和Firefox中测试了以下代码,并且惊讶地发现Firefox似乎认为它们是可迭代的,但Chrome却没有.此外,火狐认为,迭代器返回的HTMLCollection和NodeList是同一个.
var col = document.getElementsByClassName('test'); // Should get HTMLCollection of 2 elems
var nod = document.querySelectorAll('.test'); // Should get NodeList of 2 elems
var arr = [].slice.call(col); // Should get Array of 2 elems
console.log(col[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined
console.log(nod[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined
console.log(arr[Symbol.iterator]); // Firefox & Chrome: iterator function
console.log(col[Symbol.iterator] …Run Code Online (Sandbox Code Playgroud)我一直在读Go,并且难以想到这个基本问题.
在Go中,很明显切片更灵活,当您需要一系列数据时,通常可以使用切片代替数组.
阅读大部分文档,他们似乎鼓励开发人员只使用切片而不是数组.我得到的印象就像创作者可以简单地设计数组来调整大小,并且没有整个切片部分.事实上,这样的设计会使语言更容易理解,甚至可能鼓励更多惯用的代码.
那么为什么创作者首先允许阵列呢?何时使用数组而不是切片?是否有过的情况下在片数组的使用将是引人注目的?
当我查阅官方文档(http://golang.org/doc/effective_go.html#arrays)时,我发现的唯一有用的部分是:
在规划内存的详细布局时,数组很有用,有时可以帮助避免分配,但主要是它们是切片的构建块.
他们接着讨论了数组如何作为值的昂贵,以及如何用指针模拟C风格的行为.即便如此,他们还是明确地推荐了阵列部分:
但即便是这种风格也不是惯用的Go.改为使用切片.
那么,什么是"规划内存的详细布局"或"帮助避免分配"这些切片不适合的一些真实示例?
我创建了一个简单的tabe:
CREATE TABLE test (
"type" varchar,
"value" varchar,
PRIMARY KEY(type,value)
);
Run Code Online (Sandbox Code Playgroud)
我在其中插入了5行:
INSERT INTO test(type,value) VALUES('test','tag1')
INSERT INTO test(type,value) VALUES('test','tag2')
INSERT INTO test(type,value) VALUES('test','tag3')
INSERT INTO test(type,value) VALUES('test','tag4')
INSERT INTO test(type,value) VALUES('test','tag5')
Run Code Online (Sandbox Code Playgroud)
我跑了SELECT * from test LIMIT 3,它按预期工作.
type | value
------+------
test | tag1
test | tag2
test | tag3
Run Code Online (Sandbox Code Playgroud)
当我跑SELECT COUNT(*) from test LIMIT 3,它产生:
count
-------
5
Run Code Online (Sandbox Code Playgroud)
不应该说3吗?
该Datastax文件似乎表明,指定LIMIT将覆盖10000默认值.为什么在这种情况下不起作用?如果重要的话,我在Cassandra 2.2.5上并通过cqlsh运行所有查询.
更新
Java驱动程序和CQLSH都经过测试,表明LIMIT确实无法按照文档中的规定运行.如果有任何Datastax员工阅读,您的意见将非常感谢.
我们如何断言ES6地图和集合的平等?
例如:
// ES6 Map
var m1 = new Map();
m1.set('one', 1);
var m2 = new Map();
m2.set('two', 2);
assert.deepEqual(m1,m2); // outputs: passed.
// ES6 Set
var s1 = new Set();
s1.add(1);
var s2 = new Set();
s2.add(2);
assert.deepEqual(s1,s2); // outputs: passed.
Run Code Online (Sandbox Code Playgroud)
目的是断言集合/映射的元素是相等的.这两个断言都应该失败.
是否有deepEqual套装/地图的等价物?换句话说,如果没有手动迭代元素,我们如何深入测试Set/Map的平等?
如果在QUnit中没有办法,是否有适用于ES6套件和地图的单元测试工具?
编辑
在支持的Firefox中,Array.from()我一直在通过以下方式比较集合和映射:
assert.deepEqual(Array.from(m1), Array.from(m2));
Run Code Online (Sandbox Code Playgroud)
但这不适用于其他不支持的浏览器Array.from().即使使用Array.frompolyfill,Chrome/IE也不起作用 - Array.from(set)无论设置内容如何,总是会产生一个空数组.这可能是由于这些浏览器缺乏对通用迭代的支持.
其次,将其减少为数组的比较可能并不总是合适的.我们最终会得到我认为是误报的结果:
var s = new Set();
s.add([1,2]);
var m = new Map();
m.set(1,2);
assert.deepEqual(Array.from(s), Array.from(m)); // outputs: passed.
Run Code Online (Sandbox Code Playgroud)
更新 …
我试图仅使用功能性的编程构造(流,收集器,lambda表达式)来实现这一点。
假设list是一个String[]:
{"Apple", "Samsung", "LG", "Oppo", "Apple", "Huawei", "Oppo"}
Run Code Online (Sandbox Code Playgroud)
我想从此数组中打印出不同的品牌名称列表,并为其编号,即:
1. Apple
2. Huawei
3. LG
4. Oppo
5. Samsung
Run Code Online (Sandbox Code Playgroud)
我可以打印出独特的元素(排序):
Stream.of(list)
.distinct()
.sorted()
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
但这没有显示前面的计数器。我尝试过,Collectors.counting()但是那当然没有用。
FP专家有什么帮助吗?
编辑:我理解有关在带索引的流上进行迭代的其他一些问题。但是,我不能简单地做:
IntStream.range(0, list.length)
.mapToObj(a -> (a+1) + ". " + list[a])
.collect(Collectors.toList())
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
因为原始数组包含重复元素。在打印结果之前,可能还会有其他情况,map并且filter可能需要在流上执行。
在动态类型的 PHP 中,我们可以创建可以接受多种数据类型作为参数的函数。然后我们可以根据变量的类型对数据进行操作。有两种方法可以做到这一点:
方法一:
function doSomething1($param) {
$type = gettype($param);
if ($type === 'string') {
// do something
}
else if ($type === 'integer') {
// do something
}
else if ($type === 'array') {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
方法二:
function doSomething2($param) {
if (is_string($param)) {
// do something
}
else if (is_int($param)) {
// do something
}
else if (is_array($param)) {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,从测试的角度来看,这两种方法在功能上是等效的,但是由于 PHP 有很多问题,我不得不问,如果我偏爱一种方法而不是另一种方法,我是否会错过什么?
从性能的角度来看,因为PHP 函数调用很昂贵,所以说一种方法比两种方法快是正确的吗?或者是gettype()比单个is_*() …
我有一个 JavaScript 函数,它尝试将元素平滑地滚动到视图中:
dom_element.scrollIntoView({
'behavior': 'smooth',
'block': 'nearest'
});
Run Code Online (Sandbox Code Playgroud)
在 Firefox 上,这工作得很好。
但我意识到滚动是即时的,即不尊重behaviour': 'smooth'基于 Chromium 的浏览器(Chrome、Opera、Brave)。
MDN 和 caniuse.com 都显示 Chrome 支持behaviour: smooth,所以我很困惑。
经过令人沮丧的一小时调试后,我意识到如果我专门转到将Smooth Scrolling从Defaultchrome://flags/#smooth-scrolling切换到Enabled,代码就可以工作。经过一些实验,我推断出平滑滚动的Default 值意味着Disabled。
奇怪的是:在另一台计算机(笔记本电脑)上,上面的代码按预期工作,无需调整Smooth Scrolling。它被保留为默认值,滚动很流畅。
两台电脑都在 Win 10 Pro 上运行最新的 Chrome v83.0.4103.61。
问题:
针对 Chrome 上的某些PC演示此问题的代码段:
dom_element.scrollIntoView({
'behavior': 'smooth',
'block': 'nearest'
});
Run Code Online (Sandbox Code Playgroud)
let dom_target …Run Code Online (Sandbox Code Playgroud)如果我有这个数据框df1:
ABC DEF XYZ
1 9 4 1
2 4 6 9
3 7 9 8
4 6 3 8
5 1 2 3
Run Code Online (Sandbox Code Playgroud)
而这个数据帧df2:
Name
1 ABC
2 DEF
3 ABC
4 XYZ
5 ABC
Run Code Online (Sandbox Code Playgroud)
如何获得如下所示的数据框?
Name Value
1 ABC 9
2 DEF 6
3 ABC 7
4 XYZ 8
5 ABC 1
Run Code Online (Sandbox Code Playgroud) javascript ×4
ecmascript-6 ×2
performance ×2
arrays ×1
cassandra ×1
chromium ×1
cql ×1
datastax ×1
firefox ×1
go ×1
java ×1
java-stream ×1
nodelist ×1
pandas ×1
php ×1
python ×1
qunit ×1
slice ×1
types ×1
unit-testing ×1