0

我正在使用虾 pdf gem 打印 pdf。

我正在将数据格式化为表格,然后将其打印到 pdf 中。我有大约 5000 页(大约 50000 个条目)要打印,而且需要很长时间。对于少量页面,它很快......有什么办法可以提高打印速度。

此外,没有表格格式的数据的打印速度很快。这个你能帮我吗。

代码:

format.pdf {

    pdf = Prawn::Document.new(:margin => [20,20,20,20])
    pdf.font "Helvetica"
    pdf.font_size 12

    @test_points_all = Hash.new
    dataset_id = Dataset.where(collection_success: true).order('created_at DESC').first

    if(inode.leaf?)
        meta=MetricInstance.where(dataset_id: dataset_id, file_or_folder_id: inode.id).includes(:test_points,:file_or_folder,:dataset).first
        @test_points_all[inode.name] =  meta.test_points                 
    else
        nodes2 = []
        nodes2 = inode.leaves

        if(!nodes2.nil?)
            nodes2.each do |node|
                meta=MetricInstance.where(dataset_id: dataset_id, file_or_folder_id: node.id).includes(:test_points,:file_or_folder,:dataset).first
                @test_pointa = meta.test_points
                if(!@test_pointa.nil?)
                    @test_points_all[node.name] = @test_pointa
                end
            end    
        end
    end

    @test_points_all.each do |key, points|
        table_data = [["<b> #{key} </b>", "<b>433<b>","xyz","xyzs"]]
        points.each do |test|
            td=TestDescription.find(:first, :conditions=>["test_point_id=?", test.id])

            if (!td.nil?)
               table_data << ["#{test.name}","#{td.header_info}","#{td.comment_info}","#{td.line_number}"]
            end

            pdf.move_down(5)
            pdf.table(table_data, :width => 500, :cell_style => { :inline_format => true ,:border_width => 0}, :row_colors => ["FFFFFF", "DDDDDD"]) 

            pdf.text ""

            pdf.stroke do
                pdf.horizontal_line(0, 570)
            end

            pdf.move_down(5)
        end
    end


    pdf.number_pages("<page> of <total>", {
                    :start_count_at => 1,
                    :page_filter => lambda{ |pg| pg > 0 },
                    :at => [pdf.bounds.right - 50, 0],
                    :align => :right,
                    :size => 9
                  })

    pdf.render_file File.join(Rails.root, "app/reports", "x.pdf")
    filename = File.join(Rails.root, "app/reports", "x.pdf")
    send_file filename, :filename => "x.pdf", :type => "application/pdf",:disposition => "inline"
end
4

2 回答 2

2

这两行的第一行是没有意义的,把它拿出来!

nodes2 = []
nodes2 = inode.leaves

根据您的信息,我了解到以下对数据库的查询似乎执行了大约 50000 次...根据您的表的数量和内容,执行一个查询(获取整个表)可能是非常合理的在整个脚本的开头,并将此数据保存在内存中,以便在纯 Ruby 中对其执行任何后续操作,而无需与数据库对话。再说一次,如果你正在使用的桌子非常大,它也可能完全堵塞你的记忆,根本不是一个好主意。这真的取决于......所以弄清楚!

TestDescription.find(:first, :conditions=>["test_point_id=?", test.id])

此外,如果如您所说,在没有表格的情况下打印非常快,您可以通过重新实现您自己实际使用的表格功能的一小部分来实现主要的加速,而只有来自虾的低级功能。为什么?Prawn 的 table 函数肯定是为了满足尽可能多的用例,因此包括很多开销(至少从只需要准系统功能的人的角度来看——对于其他人来说,这个“开销”是黄金!)。因此,您可以自己实现您需要的那一小部分表,这可能会给您带来重大的性能提升。试一试!

于 2013-07-24T19:10:36.573 回答
0

如果您使用的是最新版本的 ActiveRecord,我建议您在内部循环中使用 pluck。而不是这个:

td=TestDescription.find(:first, :conditions=>["test_point_id=?", test.id])
if (!td.nil?)
    table_data << ["#{test.name}","#{td.header_info}","#{td.comment_info}","#{td.line_number}"]
 end

试试这个:

td = TestDescription.where(test_point_id: test.id)
  .pluck(:name, :header_info, :comment_info, :line_number).first
table_data << td unless td.blank?

无需为每个 TestDescription 实例化一个 ActiveRecord 对象,您只需返回一个应该能够直接附加到 table_data 的字段值数组,这实际上就是您所需要的。这意味着更少的内存使用和更少的 GC 时间。

尝试使用 pluck 一次检索所有条目可能也是值得的,在这种情况下,您将有一个数组数组要循环。与一次获取一个相比,这将占用更多内存,但比 AR 对象数组要少得多,并且您可以节省执行单独的数据库查询。

于 2013-09-06T15:32:24.693 回答