gpt4 book ai didi

sql - 可以加速这个算法吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:44:10 25 4
gpt4 key购买 nike

我正在尝试加速 ruby​​ 算法。我有一个 Rails 应用程序,它使用事件记录和 nokogiri 来访问数据库中的 url 列表,并从页面中抓取主图像并将其保存在与该 url 关联的图像属性下。

此 Rails 任务通常需要大约 2:30 秒才能完成,我正在努力加快它作为学习练习的速度。是否可以通过 RubyInline 和原始 SQL 代码使用 C 来实现预期的结果?我唯一的问题是,如果我使用 C,我将失去 active record with ruby​​ 所具有的数据库连接,并且不知道如何将 SQL 查询与 C 代码结合使用,以正确连接到我的数据库。

有没有人有这方面的经验,或者甚至知道这是否可能?我这样做主要是作为一种学习练习,并且想知道这是否可能。如果您有兴趣,这是我想翻译成 C 和 SQL 的代码:

task :getimg => :environment do

stories = FeedEntry.all

stories.each do |story|

if story.image.nil?

url = story.url

doc = Nokogiri::HTML(open(url))

if doc.at_css(".full-width img")
img = doc.at_css(".full-width img")[:src]
story.image = img
story.save!
elsif doc.at_css(".body-width img")
img = doc.at_css(".body-width img")[:src]
story.image = img
story.save!
elsif doc.at_css(".body-narrow-width img")
img = doc.at_css(".body-narrow-width img")[:src]
story.image = img
story.save!
elsif doc.at_css(".caption img")
img = doc.at_css(".caption img")[:src]
story.image = img
story.save!
elsif doc.at_css(".cnnArticleGalleryPhotoContainer img")
img = doc.at_css(".cnnArticleGalleryPhotoContainer img")[:src]
story.image = img
story.save!
elsif doc.at_css(".cnn_strylftcntnt div img")
img = doc.at_css(".cnn_strylftcntnt div img")[:src]
story.image = img
story.save!
elsif doc.at_css(".cnn_stryimg640captioned img")
img = doc.at_css(".cnn_stryimg640captioned img")[:src]
story.image = img
story.save!
end
else
#do nothing
end
end
end

我将不胜感激在这件事上的任何和所有帮助和见解。提前致谢!!

最佳答案

数据库保存速度

我用 ruby​​ 编写了一个网络爬虫,我发现可能影响性能的瓶颈之一是在数据库中实际创建行。在提取所有 URL 的末尾有一个单一的大量 insert 比有多个单独的插入更快(至少对于 Postgres)。

因此,无需为您访问的每个 url 调用 YourModel.save!,只需将每个 url 推送到一个数组,该数组将跟踪您需要保存到数据库的 url。然后,一旦您完成所有链接的抓取,通过 sql 命令批量插入所有图像链接。

stories.each do |story|
url = story.url
doc = Nokogiri::HTML(open(url))

img_url = doc.at_css("img")[:src]
to_insert.push "(#{img_url})"
end
#notice the mass insert at the end
sql = "INSERT INTO your_table (img_url) VALUES #{to_insert.join(", ")}"

#CONN is a constant declared at the top of your file (CONN = ActiveRecord::Base.connection)
#that connects to the database
CONN.execute sql

“加速”下载

链接的下载也会成为瓶颈。因此,最好的选择是创建一个线程池,其中为每个线程分配一个来自数据库的 URL 分区以进行抓取。这样,您就不会在进行任何实际处理之前等待单个页面的下载。

一些伪 ruby 代码:

number_of_workers = 10
(1..number_of_workers).each do |worker|
Thread.new do
begin
urls_to_scrape_for_this_thread = [...list of urls to scrape...]
while urls_to_scrape > 0
url = take_one_url_from_list
scrape(url)
end
rescue => e
puts "========================================"
puts "Thread # #{i} error"
puts "#{e.message}"
puts "#{e.backtrace}"
puts "======================================="
raise e
end
end
end

关于sql - 可以加速这个算法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30299296/

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