]> https://gitweb.dealii.org/ - dealii.git/commitdiff
use binary search in BlockIndices::global_to_local() 7699/head
authorDenis Davydov <davydden@gmail.com>
Wed, 6 Feb 2019 13:18:56 +0000 (14:18 +0100)
committerDenis Davydov <davydden@gmail.com>
Wed, 6 Feb 2019 13:22:39 +0000 (14:22 +0100)
doc/news/changes/minor/20190206DenisDavydov [new file with mode: 0644]
include/deal.II/lac/block_indices.h
tests/lac/block_indices_02.cc [new file with mode: 0644]
tests/lac/block_indices_02.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20190206DenisDavydov b/doc/news/changes/minor/20190206DenisDavydov
new file mode 100644 (file)
index 0000000..73aa3ed
--- /dev/null
@@ -0,0 +1,4 @@
+Improved: Use binary search in BlockIndices::global_to_local() to improve performance
+for large number of blocks.
+<br>
+(Denis Davydov, 2019/02/06)
index 6ada38375a72900283fc3957572e4f2d62d76122..ef81f81c6e543d3fee34a3a7cdb8c930bf5e11a6 100644 (file)
@@ -333,11 +333,11 @@ BlockIndices::global_to_local(const size_type i) const
   Assert(i < total_size(), ExcIndexRangeType<size_type>(i, 0, total_size()));
   Assert(n_blocks > 0, ExcLowerRangeType<size_type>(i, size_type(1)));
 
-  unsigned int block = n_blocks - 1;
-  while (i < start_indices[block])
-    --block;
+  // start_indices[0] == 0 so we might as well start from the next one
+  const auto it =
+    --std::upper_bound(++start_indices.begin(), start_indices.end(), i);
 
-  return {block, i - start_indices[block]};
+  return {std::distance(start_indices.begin(), it), i - *it};
 }
 
 
diff --git a/tests/lac/block_indices_02.cc b/tests/lac/block_indices_02.cc
new file mode 100644 (file)
index 0000000..0d2cc2c
--- /dev/null
@@ -0,0 +1,60 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+// Test BlockIndices::global_to_local() for very large number of blocks
+
+#include <deal.II/lac/block_indices.h>
+
+#include "../tests.h"
+
+
+
+void
+test()
+{
+  constexpr unsigned int            n_blocks   = 10000;
+  constexpr types::global_dof_index block_size = 3;
+  constexpr types::global_dof_index size       = n_blocks * block_size;
+  BlockIndices                      idx(n_blocks, block_size);
+
+  const std::vector<types::global_dof_index> is = {{0,
+                                                    1,
+                                                    block_size * 500 + 2,
+                                                    block_size * 600,
+                                                    block_size * 701 - 1,
+                                                    size - 1}};
+
+  deallog << "n_blocks:   " << n_blocks << std::endl
+          << "block_size: " << block_size << std::endl
+          << "size:       " << idx.size() << std::endl;
+  for (auto i : is)
+    {
+      const auto p = idx.global_to_local(i);
+      AssertDimension(p.first, i / block_size);
+      AssertDimension(p.second, i % block_size);
+      deallog << i << " -> (" << p.first << "," << p.second << ")" << std::endl;
+    }
+
+  deallog << std::endl;
+}
+
+
+int
+main()
+{
+  initlog();
+  test();
+}
diff --git a/tests/lac/block_indices_02.output b/tests/lac/block_indices_02.output
new file mode 100644 (file)
index 0000000..6265aaf
--- /dev/null
@@ -0,0 +1,11 @@
+
+DEAL::n_blocks:   10000
+DEAL::block_size: 3
+DEAL::size:       10000
+DEAL::0 -> (0,0)
+DEAL::1 -> (0,1)
+DEAL::1502 -> (500,2)
+DEAL::1800 -> (600,0)
+DEAL::2102 -> (700,2)
+DEAL::29999 -> (9999,2)
+DEAL::

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.