javascript - Photoshop 中的 Js 比 Chrome 中的慢。我可以更快地制作两个 for 循环吗?
问题描述
以下代码生成随机点(x,y),然后对于每个点,它将画布(一个正方形)分成四个。对于迭代中的下一个点,它会搜索该点所在的方格,并将其分成四个较小的方格——最大为一定的方格大小。
问题是它在 Chrome 中运行非常快,在 Ps 中运行非常慢(11k 点在 Chrome 中需要 2 秒,在 Ps 中需要 30 分钟!对于 1k 点,在 Ps 中需要大约 10 秒。
有没有更好的重写这个?顺便说一句,PS 不支持 ES5
var squares = [];
var canvaswidth = app.activeDocument.width.as("px");
var canvasheight = app.activeDocument.height.as("px");
squares.push([{
x: 0,
y: 0
}, {
x: canvaswidth,
y: 0
}, {
x: canvaswidth,
y: canvasheight
}, {
x: 0,
y: canvasheight
}])
vertices = [];
for (i = 0; i < 8000; i++) {
vertices.push({
x: Math.floor(Math.random() * canvaswidth),
y: Math.floor(Math.random() * canvasheight)
})
}
var t0 = new Date().getTime();
var minsquaresize = 24;
for (v = 0; v < vertices.length; v++) {
if (v > 0 && Math.abs(vertices[v].x - vertices[v - 1].x) > minsquaresize && Math.abs(vertices[v].y - vertices[v - 1].y) > minsquaresize) {
r = 2;
for (s = 0; s < squares.length; s++) {
var squares_s = squares[s];
if (squares_s != undefined && vertices[v].x >= squares_s[0].x && vertices[v].x <= squares_s[2].x && vertices[v].y >= squares_s[0].y && vertices[v].y <= squares_s[2].y && squares_s[1].x - squares_s[0].x > minsquaresize && squares_s[3].y - squares_s[0].y > minsquaresize) {
var s1p1 = {
x: Math.round(squares_s[0].x),
y: Math.round(squares_s[0].y)
};
var s1p2 = {
x: Math.round((squares_s[0].x + squares_s[1].x) / 2),
y: Math.round((squares_s[0].y + squares_s[1].y) / 2)
};
var s1p3 = {
x: Math.round(((squares_s[1].x - squares_s[0].x) / r) + squares_s[0].x),
y: Math.round(((squares_s[3].y - squares_s[0].y) / r) + squares_s[0].y)
}
var s1p4 = {
x: (squares_s[0].x + squares_s[3].x) / 2,
y: Math.round((squares_s[0].y + squares_s[3].y) / 2)
}
var s2p2 = {
x: squares_s[1].x,
y: squares_s[1].y
}
var s2p3 = {
x: Math.round((squares_s[1].x + squares_s[2].x) / 2),
y: Math.round((squares_s[1].y + squares_s[2].y) / 2)
}
var s3p3 = {
x: squares_s[2].x,
y: squares_s[2].y
}
var s3p4 = {
x: Math.round((squares_s[2].x + squares_s[3].x) / 2),
y: Math.round(Math.round((squares_s[2].y + squares_s[3].y) / 2))
}
var s4p4 = {
x: squares_s[3].x,
y: squares_s[3].y
}
//alert(s4p4.y)
delete squares[s];
squares.push([s1p1, s1p2, s1p3, s1p4])
squares.push([s1p2, s2p2, s2p3, s1p3])
squares.push([s1p3, s2p3, s3p3, s3p4])
squares.push([s1p4, s1p3, s3p4, s4p4])
break;
}
}
}
}
var t1 = new Date().getTime() - t0;
alert("time: "+t1)
解决方案
通过反向循环正方形来管理显着的性能提升。所以通常是:
for(vertices length, v++){
for(squares length, s++){
if vertex is within square then delete square from square array, split square into 4 equal squares and add them to array
}
}
顶点是从路径中收集的,因此顶点 4 可能靠近顶点 3,因此可能在从顶点 3 创建的最后一个正方形的区域中 - 在正方形数组的末尾。所以:
for(var s = squares.length; s--;){...}
这工作得更快(可能是 10 倍)。奇怪的是,随机放置的顶点也更快。
推荐阅读
- ruby-on-rails - Rspec - 测试方法的实例
- java - Gradle 使用新 Java 构建良好,但在 Java 11 上缺少兄弟项目
- c# - 如何强制自定义事件处理程序正常工作
- gcc - 在安装期间减少 GCC 输出
- python - 在 Tensorflow 决策森林中提取样本的叶子指数
- recharts - 带标签的两行图表
- javascript - 在执行某些代码之前是否可以隐藏弹出窗口?
- excel - Excel公式将日期时间戳与今天的日期进行比较
- javascript - 使用 date-fns 根据用户区域设置格式化日期
- php - 如何在 Laravel 视图中显示 stdClass 类型对象,例如 SQL Sum() 语句的结果?