gpt4 book ai didi

ruby - Watir:使用不同的 DOM 选择方法读取所用时间的差异

转载 作者:数据小太阳 更新时间:2023-10-29 08:35:37 26 4
gpt4 key购买 nike

我正在使用 Watir 来测试我的网络应用程序。我使用 CSS 选择器来访问各种元素。在下面的示例中,我试图从表中读取所有数据。

在第一种方法中,我获取所有表格行,然后从行中的每个单元格中读取文本。

在第二种方法中,我使用选择器读取每个单元格。我很惊讶第二个比第一个快三倍左右。

方法一:

rows = $browser.table(:id,"bin_die_count").rows
while index < rows.count
bin_details = {}
speed_grade = rows[index][2].text
die_count = rows[index][3].text
bin_value = rows[index][0].text
bin_details = {"speed_grade" => speed_grade, "die_count" => die_count}
all_bin_details[bin_value] = bin_details
puts bin_details
index = index + 1
end

方法二:

row_count = $browser.table(:id,"bin_die_count").rows.count
while index < rows.count
bin_details = {}
speed_grade = $browser.element(:css,"#bin_die_count > tbody > tr:nth-child(#{index}) > td:nth-child(3)").text
die_count = $browser.element(:css,"#bin_die_count > tbody > tr:nth-child(#{index}) > td:nth-child(4)").text
bin_value = $browser.element(:css,"#bin_die_count > tbody > tr:nth-child(#{index}) > td:nth-child(1)").text
bin_details = {"speed_grade" => speed_grade, "die_count" => die_count}
all_bin_details[bin_value] = bin_details
puts bin_details
index = index + 1
end

此处方法 1 花费了 46.555 秒完成,方法 2 花费了 16.025 秒。我期望方法 1 更快,因为它指的是行中的相对文本,但方法 2 指的是每个文本都带有绝对 CSS 选择器。

这是为什么?

最佳答案

问题

决定性能的最大因素是有线调用的次数 - 即 Watir 要求 Selenium 与浏览器对话的次数。

在第一种方法中,我已将其简化为 rows[0][0].text,您会看到以下 8 个线调用:

2017-07-31 11:45:37 INFO Selenium -> POST session/a248a69dfd9ae930072e4a3dbe5a979f/elements
2017-07-31 11:45:37 INFO Selenium >>> http://127.0.0.1:9515/session/a248a69dfd9ae930072e4a3dbe5a979f/elements | {"using":"tag name","value":"tr"}
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":[{"ELEMENT":"0.9824074557261091-1"},{"ELEMENT":"0.9824074557261091-2"}]}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-1/enabled
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":true}
2017-07-31 11:45:37 INFO Selenium -> POST session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-1/elements
2017-07-31 11:45:37 INFO Selenium >>> http://127.0.0.1:9515/session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-1/elements | {"using":"xpath","value":"./th | ./td"}
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":[{"ELEMENT":"0.9824074557261091-3"},{"ELEMENT":"0.9824074557261091-4"},{"ELEMENT":"0.9824074557261091-5"},{"ELEMENT":"0.9824074557261091-6"}]}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-3/name
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":"td"}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-4/name
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":"td"}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-5/name
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":"td"}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-6/name
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":"td"}
2017-07-31 11:45:37 INFO Selenium -> GET session/a248a69dfd9ae930072e4a3dbe5a979f/element/0.9824074557261091-3/text
2017-07-31 11:45:37 INFO Selenium <- {"sessionId":"a248a69dfd9ae930072e4a3dbe5a979f","status":0,"value":"Product"}

相比之下,第二种方法再次简化为 browser.td(:css,"#bin_die_count > tbody > tr:nth-child(1) > td:nth-child(1)").text ,只有 3 个电汇电话:

2017-07-31 11:46:33 INFO Selenium -> POST session/f19ba6fd8cf948b590b36f3c77191624/element
2017-07-31 11:46:33 INFO Selenium >>> http://127.0.0.1:9515/session/f19ba6fd8cf948b590b36f3c77191624/element | {"using":"css selector","value":"#bin_die_count > tbody > tr:nth-child(1) > td:nth-child(1)"}
2017-07-31 11:46:33 INFO Selenium <- {"sessionId":"f19ba6fd8cf948b590b36f3c77191624","status":0,"value":{"ELEMENT":"0.8228824382277831-1"}}
2017-07-31 11:46:33 INFO Selenium -> GET session/f19ba6fd8cf948b590b36f3c77191624/element/0.8228824382277831-1/name
2017-07-31 11:46:33 INFO Selenium <- {"sessionId":"f19ba6fd8cf948b590b36f3c77191624","status":0,"value":"td"}
2017-07-31 11:46:33 INFO Selenium -> GET session/f19ba6fd8cf948b590b36f3c77191624/element/0.8228824382277831-1/text
2017-07-31 11:46:33 INFO Selenium <- {"sessionId":"f19ba6fd8cf948b590b36f3c77191624","status":0,"value":"Product"}

第二种方法的连线调用数量不到一半,因此执行时间大约减少了一半。

看起来第一种方法花费时间较长的主要原因是在获取 td 元素的集合时,每个 td 元素的标签名称都经过验证。例如,包含 3 个 td 元素的行将对名称进行 3 次连线调用,具有 4 个 td 元素的行将对名称进行 4 次连线调用,等等。在相比之下,第二种方法只需要获取一个特定的 td 元素。表越大,第二种方法节省的时间就越多。

解决方案 - 使用一行中的几个单元格

如果您只是挑选出一行中的几个单元格,您可以通过定位特定的 td 而不调用集合来避免使用 CSS 选择器:

rows[0].td(index: 0).text

这提供了与 CSS 选择器类似的性能。在获取包含 25 个 td 元素的一行中的单个 td 文本时,可以看到以下性能:

rows = browser.trs
puts Benchmark.measure { 100.times { rows[0][0].text } }
#=> 45.781881

puts Benchmark.measure { 100.times { browser.td(:css,"#bin_die_count > tbody > tr:nth-child(1) > td:nth-child(1)").text } }
#=> 4.832999

rows = browser.trs
puts Benchmark.measure { 100.times { rows[0].td(index: 0).text } }
#=> 4.812138

解决方案 - 使用一行中的多个单元格

如果您正在使用该行的许多 td 元素,您最好获取元素的集合。但是,您应该为该行执行一次,而不是为您需要的每个单元格执行一次。例如:

row_tds = rows[index].tds
speed_grade = row_tds[2].text
die_count = row_tds[3].text
bin_value = row_tds[0].text

正如您在下面的性能结果中看到的,一次获取整个集合比单独访问每个单元格更快:

rows = browser.trs
puts Benchmark.measure { 20.times { (1..24).map { |i| rows[0].td(index: i).text } } }
#=> 18.776798

rows = browser.trs
puts Benchmark.measure { 20.times { tds = rows[0].tds; tds.map(&:text) } }
#=> 13.478259

关于ruby - Watir:使用不同的 DOM 选择方法读取所用时间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45418199/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com