为什么最后一次 "ResultSet.next()" 迭代比之前的迭代花费更多时间?
Why does the last "ResultSet.next()"-iteration take way more time than the previous iterations?
我的 "while(res.next())" 循环的最后一次迭代需要 1.5 秒,而之前的迭代只需要大约 0,003 毫秒。我很困惑。
我使用一个常见的 JDBC 查询从我的 SQLite 数据库中获取一个结果集。 ResultSet 并不大,它总是 4 列宽,0 到 100 行长。然后我想将 ResultSet 数据保存在 POJO 中并将这些 POJO 存储在 ArrayList 中。我使用通常的迭代方法,您只需放置一个 "while(res.next())" 循环并迭代整个 ResultSet。我发现我的代码中存在瓶颈,可以将其缩小到 while(res.next()) 循环。我开始调试并测量代码中的执行时间,结果发现最后一个 .next() 调用(应该 return false 以便循环停止)需要很长时间。
ArrayList<Trade> trades = new ArrayList<>();
try
{
Statement statement = connector.getConnection().createStatement();
statement.setFetchSize(1337);
ResultSet res = statement.executeQuery("SELECT * FROM trades WHERE timestamp >= 0 AND timestamp < 1337;");
res.setFetchSize(1337);
int numberOfTrades = 0;
long startTime = System.nanoTime();
while(res.next())
{
long addObjectTime = System.nanoTime();
trades.add(new Trade(res.getLong("id"),res.getLong("timestamp"),res.getDouble("price"),res.getDouble("amount")));
numberOfTrades++;
System.out.println("Added trade to list within "+(System.nanoTime()-addObjectTime)+"ns.");
}
System.out.println("List-creation completed within "+(System.nanoTime()-startTime)+"ns.");
System.out.println("Number of trades: "+numberOfTrades);
} catch (SQLException e)
{
e.printStackTrace();
}
这是我的代码。如您所见,我已经尝试使用各种 fetchSizes,正如其他人在性能线程中提到的有关 .next() 方法的那样。我尽我所能,但结果仍然是这样的:
Added trade to list within 46000ns.
Added trade to list within 3200ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 4500ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 3100ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2400ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2200ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 11100ns.
List-creation completed within 1548543200ns.
Number of trades: 22
使用 ResultSet 中的数据将 POJO 添加到我的 ArrayList 通常需要 2-5 微秒。所以总而言之,循环的时间应该不会比添加交易的所有执行时间加起来长很多,对吗?在我的例子中是 0,1073 毫秒。相反,循环总共花费超过 1.5 秒,这是我预期的 10,000 倍。我实际上对这里发生的事情一无所知。这对我的程序来说是一个严重的问题,因为代码片段执行了大约 100,000 次,所以 150,000 秒将是 40 小时的性能损失:(
我确实解决了这个问题,但我不是 100% 确定为什么现在解决了。我正在查询的数据库有数百万个条目,并且总是通过单个列(时间戳)访问。我索引了时间戳,性能问题完全消失了。我仍然不知道为什么 .next() 方法的行为如此。
我的 "while(res.next())" 循环的最后一次迭代需要 1.5 秒,而之前的迭代只需要大约 0,003 毫秒。我很困惑。
我使用一个常见的 JDBC 查询从我的 SQLite 数据库中获取一个结果集。 ResultSet 并不大,它总是 4 列宽,0 到 100 行长。然后我想将 ResultSet 数据保存在 POJO 中并将这些 POJO 存储在 ArrayList 中。我使用通常的迭代方法,您只需放置一个 "while(res.next())" 循环并迭代整个 ResultSet。我发现我的代码中存在瓶颈,可以将其缩小到 while(res.next()) 循环。我开始调试并测量代码中的执行时间,结果发现最后一个 .next() 调用(应该 return false 以便循环停止)需要很长时间。
ArrayList<Trade> trades = new ArrayList<>();
try
{
Statement statement = connector.getConnection().createStatement();
statement.setFetchSize(1337);
ResultSet res = statement.executeQuery("SELECT * FROM trades WHERE timestamp >= 0 AND timestamp < 1337;");
res.setFetchSize(1337);
int numberOfTrades = 0;
long startTime = System.nanoTime();
while(res.next())
{
long addObjectTime = System.nanoTime();
trades.add(new Trade(res.getLong("id"),res.getLong("timestamp"),res.getDouble("price"),res.getDouble("amount")));
numberOfTrades++;
System.out.println("Added trade to list within "+(System.nanoTime()-addObjectTime)+"ns.");
}
System.out.println("List-creation completed within "+(System.nanoTime()-startTime)+"ns.");
System.out.println("Number of trades: "+numberOfTrades);
} catch (SQLException e)
{
e.printStackTrace();
}
这是我的代码。如您所见,我已经尝试使用各种 fetchSizes,正如其他人在性能线程中提到的有关 .next() 方法的那样。我尽我所能,但结果仍然是这样的:
Added trade to list within 46000ns.
Added trade to list within 3200ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 4500ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 3100ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2400ns.
Added trade to list within 2400ns.
Added trade to list within 2300ns.
Added trade to list within 2200ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 2300ns.
Added trade to list within 11100ns.
List-creation completed within 1548543200ns.
Number of trades: 22
使用 ResultSet 中的数据将 POJO 添加到我的 ArrayList 通常需要 2-5 微秒。所以总而言之,循环的时间应该不会比添加交易的所有执行时间加起来长很多,对吗?在我的例子中是 0,1073 毫秒。相反,循环总共花费超过 1.5 秒,这是我预期的 10,000 倍。我实际上对这里发生的事情一无所知。这对我的程序来说是一个严重的问题,因为代码片段执行了大约 100,000 次,所以 150,000 秒将是 40 小时的性能损失:(
我确实解决了这个问题,但我不是 100% 确定为什么现在解决了。我正在查询的数据库有数百万个条目,并且总是通过单个列(时间戳)访问。我索引了时间戳,性能问题完全消失了。我仍然不知道为什么 .next() 方法的行为如此。