Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better FrontCodedIndexed #13854

Merged

Conversation

clintropolis
Copy link
Member

@clintropolis clintropolis commented Feb 27, 2023

Description

Iterating on #12277 to continue experimentation, this PR introduces 'V1' of FrontCodedIndexed, the backing structure of the frontCoded string encoding strategy. This version stores values in buckets based on a prefix of the previous value instead of the first value in the bucket like v0. This improves overall storage size, particularly with using larger buckets.

Internally, it adds a new useIncrementalBuckets option to FrontCodedIndexedWriter, which is always set to true to cause it to write out the new version of FrontCodedIndexed. The flag remains so tests can still write V0, and V0 coexists with V1 inside of the FrontCodedIndexed as well for backwards compatibility.

AFC4B099-CC5D-4564-87D6-7151AE606FF8 2

Benchmarks

I think the benchmarks look good enough (or even better in many cases) to make this new mode the only mode for front-coded (which itself is still not the default).

Segment sizes
768M	./foo_2000-01-01T00:00:00.000Z_2000-01-02T00:00:00.000Z_front-coded-16_9de75fc71fbfa1f214d5045eb2d71d46393ca3285b6733c368313fda78190dd6
771M	./foo_2000-01-01T00:00:00.000Z_2000-01-02T00:00:00.000Z_front-coded-4-incremental_82ba2335484097c10bec7ce5bc001f74c3b120bb4c1647ebaf07cffc1d178fc6
772M	./foo_2000-01-01T00:00:00.000Z_2000-01-02T00:00:00.000Z_front-coded-4_18e18e85cbf255c75fca4c8dba716219ba057de9ad61208253aeeda97f2c6b7e
847M	./foo_2000-01-01T00:00:00.000Z_2000-01-02T00:00:00.000Z_none_9dcb5c6841437f0ec534c39e5ddb90478ec3b80e592659fc0ba0a5e16f044bce
765M	./foo_2000-01-01T00:00:00.000Z_2000-01-02T00:00:00.000Z_front-coded-16-incremental_4d921dbf2c78dcf3f06ac308d57ef357503d338fec3b2eee996def832424418f
Query times
SELECT SUM(sumLongSequential), SUM(sumFloatNormal) FROM foo WHERE dimSequential NOT LIKE '%3'

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score    Error  Units
SqlBenchmark.querySql        4           5000000           mmap                        none        false  avgt    3   99.352 ±  0.436  ms/op
SqlBenchmark.querySql        4           5000000           mmap               front-coded-4        false  avgt    3   87.869 ±  9.633  ms/op
SqlBenchmark.querySql        4           5000000           mmap              front-coded-16        false  avgt    3   91.834 ±  4.909  ms/op
SqlBenchmark.querySql        4           5000000           mmap   front-coded-4-incremental        false  avgt    3   91.643 ±  2.694  ms/op
SqlBenchmark.querySql        4           5000000           mmap  front-coded-16-incremental        false  avgt    3   87.405 ±  3.943  ms/op

SqlBenchmark.querySql        4           5000000           mmap                        none        force  avgt    3   58.105 ±  2.681  ms/op
SqlBenchmark.querySql        4           5000000           mmap               front-coded-4        force  avgt    3   96.755 ±  0.522  ms/op
SqlBenchmark.querySql        4           5000000           mmap              front-coded-16        force  avgt    3   63.194 ±  2.207  ms/op
SqlBenchmark.querySql        4           5000000           mmap   front-coded-4-incremental        force  avgt    3   57.345 ±  0.695  ms/op
SqlBenchmark.querySql        4           5000000           mmap  front-coded-16-incremental        force  avgt    3   55.702 ± 33.098  ms/op
SELECT SUM(sumLongSequential), SUM(sumFloatNormal) FROM foo WHERE dimSequential = '311'

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score    Error  Units
SqlBenchmark.querySql        5           5000000           mmap                        none        false  avgt    3   43.212 ±  2.750  ms/op
SqlBenchmark.querySql        5           5000000           mmap               front-coded-4        false  avgt    3   45.994 ±  1.239  ms/op
SqlBenchmark.querySql        5           5000000           mmap              front-coded-16        false  avgt    3   42.225 ± 15.826  ms/op
SqlBenchmark.querySql        5           5000000           mmap   front-coded-4-incremental        false  avgt    3   44.729 ±  2.044  ms/op
SqlBenchmark.querySql        5           5000000           mmap  front-coded-16-incremental        false  avgt    3   41.272 ± 10.058  ms/op

SqlBenchmark.querySql        5           5000000           mmap                        none        force  avgt    3   39.653 ±  0.435  ms/op
SqlBenchmark.querySql        5           5000000           mmap               front-coded-4        force  avgt    3   36.766 ±  0.668  ms/op
SqlBenchmark.querySql        5           5000000           mmap              front-coded-16        force  avgt    3   38.507 ±  4.516  ms/op
SqlBenchmark.querySql        5           5000000           mmap   front-coded-4-incremental        force  avgt    3   35.893 ±  2.018  ms/op
SqlBenchmark.querySql        5           5000000           mmap  front-coded-16-incremental        force  avgt    3   36.929 ±  2.367  ms/op
SELECT SUM(sumLongSequential), SUM(sumFloatNormal) FROM foo WHERE dimSequential NOT LIKE '%3' AND maxLongUniform > 10

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score    Error  Units
SqlBenchmark.querySql        6           5000000           mmap                        none        false  avgt    3   56.631 ±  2.492  ms/op
SqlBenchmark.querySql        6           5000000           mmap               front-coded-4        false  avgt    3   59.273 ±  6.659  ms/op
SqlBenchmark.querySql        6           5000000           mmap              front-coded-16        false  avgt    3   62.308 ±  6.472  ms/op
SqlBenchmark.querySql        6           5000000           mmap   front-coded-4-incremental        false  avgt    3   61.663 ±  0.507  ms/op
SqlBenchmark.querySql        6           5000000           mmap  front-coded-16-incremental        false  avgt    3   61.764 ±  1.579  ms/op

SqlBenchmark.querySql        6           5000000           mmap                        none        force  avgt    3   34.302 ±  0.429  ms/op
SqlBenchmark.querySql        6           5000000           mmap               front-coded-4        force  avgt    3   32.906 ± 13.682  ms/op
SqlBenchmark.querySql        6           5000000           mmap              front-coded-16        force  avgt    3   30.824 ±  2.512  ms/op
SqlBenchmark.querySql        6           5000000           mmap   front-coded-4-incremental        force  avgt    3   38.140 ±  0.838  ms/op
SqlBenchmark.querySql        6           5000000           mmap  front-coded-16-incremental        force  avgt    3   30.068 ±  0.119  ms/op
SELECT SUM(sumLongSequential) FILTER(WHERE dimSequential = '311'), SUM(sumFloatNormal) FROM foo WHERE dimSequential NOT LIKE '%3'

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score    Error  Units
SqlBenchmark.querySql        7           5000000           mmap                        none        false  avgt    3  385.114 ±  7.824  ms/op
SqlBenchmark.querySql        7           5000000           mmap               front-coded-4        false  avgt    3  126.507 ± 11.895  ms/op
SqlBenchmark.querySql        7           5000000           mmap              front-coded-16        false  avgt    3  383.743 ±  4.948  ms/op
SqlBenchmark.querySql        7           5000000           mmap   front-coded-4-incremental        false  avgt    3  393.450 ±  9.118  ms/op
SqlBenchmark.querySql        7           5000000           mmap  front-coded-16-incremental        false  avgt    3  122.711 ±  3.370  ms/op

SqlBenchmark.querySql        7           5000000           mmap                        none        force  avgt    3   65.453 ±  1.827  ms/op
SqlBenchmark.querySql        7           5000000           mmap               front-coded-4        force  avgt    3   65.742 ±  3.248  ms/op
SqlBenchmark.querySql        7           5000000           mmap              front-coded-16        force  avgt    3   67.534 ±  4.976  ms/op
SqlBenchmark.querySql        7           5000000           mmap   front-coded-4-incremental        force  avgt    3   61.965 ±  0.294  ms/op
SqlBenchmark.querySql        7           5000000           mmap  front-coded-16-incremental        force  avgt    3   61.407 ±  2.353  ms/op
SELECT
  SUM(sumLongSequential) FILTER(WHERE dimSequential = '311'),
  SUM(sumLongSequential) FILTER(WHERE dimSequential <> '311'),
  SUM(sumLongSequential) FILTER(WHERE dimSequential LIKE '%3'),
  SUM(sumLongSequential) FILTER(WHERE dimSequential NOT LIKE '%3'),
  SUM(sumLongSequential),
  SUM(sumFloatNormal) FILTER(WHERE dimSequential = '311'),
  SUM(sumFloatNormal) FILTER(WHERE dimSequential <> '311'),
  SUM(sumFloatNormal) FILTER(WHERE dimSequential LIKE '%3'),
  SUM(sumFloatNormal) FILTER(WHERE dimSequential NOT LIKE '%3'),
  SUM(sumFloatNormal),
  COUNT(*) FILTER(WHERE dimSequential = '311'),
  COUNT(*) FILTER(WHERE dimSequential <> '311'),
  COUNT(*) FILTER(WHERE dimSequential LIKE '%3'),
  COUNT(*) FILTER(WHERE dimSequential NOT LIKE '%3'),
  COUNT(*)
FROM foo

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql        8           5000000           mmap                        none        false  avgt    3  893.483 ±  122.749  ms/op
SqlBenchmark.querySql        8           5000000           mmap               front-coded-4        false  avgt    3  933.899 ±   65.865  ms/op
SqlBenchmark.querySql        8           5000000           mmap              front-coded-16        false  avgt    3  903.173 ±   18.705  ms/op
SqlBenchmark.querySql        8           5000000           mmap   front-coded-4-incremental        false  avgt    3  922.902 ±   44.813  ms/op
SqlBenchmark.querySql        8           5000000           mmap  front-coded-16-incremental        false  avgt    3  933.547 ±   18.189  ms/op

SqlBenchmark.querySql        8           5000000           mmap                        none        force  avgt    3  479.690 ±   10.704  ms/op
SqlBenchmark.querySql        8           5000000           mmap               front-coded-4        force  avgt    3  442.920 ±    8.947  ms/op
SqlBenchmark.querySql        8           5000000           mmap              front-coded-16        force  avgt    3  449.478 ±   22.717  ms/op
SqlBenchmark.querySql        8           5000000           mmap   front-coded-4-incremental        force  avgt    3  456.628 ±    4.066  ms/op
SqlBenchmark.querySql        8           5000000           mmap  front-coded-16-incremental        force  avgt    3  461.933 ±  387.758  ms/op
SELECT dimSequential, dimZipf, SUM(sumLongSequential) FROM foo GROUP BY 1, 2

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql       10           5000000           mmap                        none        false  avgt    3  378.979 ±  347.293  ms/op
SqlBenchmark.querySql       10           5000000           mmap               front-coded-4        false  avgt    3  460.106 ±  714.876  ms/op
SqlBenchmark.querySql       10           5000000           mmap              front-coded-16        false  avgt    3  448.615 ± 1771.130  ms/op
SqlBenchmark.querySql       10           5000000           mmap   front-coded-4-incremental        false  avgt    3  404.706 ±  722.758  ms/op
SqlBenchmark.querySql       10           5000000           mmap  front-coded-16-incremental        false  avgt    3  436.118 ±  366.513  ms/op

SqlBenchmark.querySql       10           5000000           mmap                        none        force  avgt    3  229.117 ±    9.454  ms/op
SqlBenchmark.querySql       10           5000000           mmap               front-coded-4        force  avgt    3  323.579 ±   71.747  ms/op
SqlBenchmark.querySql       10           5000000           mmap              front-coded-16        force  avgt    3  241.397 ±    8.582  ms/op
SqlBenchmark.querySql       10           5000000           mmap   front-coded-4-incremental        force  avgt    3  247.793 ±   88.436  ms/op
SqlBenchmark.querySql       10           5000000           mmap  front-coded-16-incremental        force  avgt    3  253.020 ±   52.350  ms/op
SELECT dimSequential, dimZipf, SUM(sumLongSequential), COUNT(*) FROM foo GROUP BY 1, 2

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql       11           5000000           mmap                        none        false  avgt    3  387.061 ±  141.763  ms/op
SqlBenchmark.querySql       11           5000000           mmap               front-coded-4        false  avgt    3  444.895 ±  928.869  ms/op
SqlBenchmark.querySql       11           5000000           mmap              front-coded-16        false  avgt    3  509.440 ±  413.921  ms/op
SqlBenchmark.querySql       11           5000000           mmap   front-coded-4-incremental        false  avgt    3  481.594 ±  623.389  ms/op
SqlBenchmark.querySql       11           5000000           mmap  front-coded-16-incremental        false  avgt    3  394.582 ±   58.469  ms/op

SqlBenchmark.querySql       11           5000000           mmap                        none        force  avgt    3  239.468 ±   47.360  ms/op
SqlBenchmark.querySql       11           5000000           mmap               front-coded-4        force  avgt    3  260.571 ±   49.548  ms/op
SqlBenchmark.querySql       11           5000000           mmap              front-coded-16        force  avgt    3  271.968 ±  266.563  ms/op
SqlBenchmark.querySql       11           5000000           mmap   front-coded-4-incremental        force  avgt    3  273.136 ±  630.701  ms/op
SqlBenchmark.querySql       11           5000000           mmap  front-coded-16-incremental        force  avgt    3  256.577 ±   24.896  ms/op
SELECT dimZipf FROM foo GROUP BY 1

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql       12           5000000           mmap                        none        false  avgt    3   50.249 ±    4.175  ms/op
SqlBenchmark.querySql       12           5000000           mmap               front-coded-4        false  avgt    3   49.342 ±    1.057  ms/op
SqlBenchmark.querySql       12           5000000           mmap              front-coded-16        false  avgt    3   50.851 ±    1.668  ms/op
SqlBenchmark.querySql       12           5000000           mmap   front-coded-4-incremental        false  avgt    3   49.551 ±    4.030  ms/op
SqlBenchmark.querySql       12           5000000           mmap  front-coded-16-incremental        false  avgt    3   49.439 ±    2.108  ms/op

SqlBenchmark.querySql       12           5000000           mmap                        none        force  avgt    3   23.244 ±    1.174  ms/op
SqlBenchmark.querySql       12           5000000           mmap               front-coded-4        force  avgt    3   25.351 ±   12.693  ms/op
SqlBenchmark.querySql       12           5000000           mmap              front-coded-16        force  avgt    3   25.323 ±    8.445  ms/op
SqlBenchmark.querySql       12           5000000           mmap   front-coded-4-incremental        force  avgt    3   24.046 ±    7.110  ms/op
SqlBenchmark.querySql       12           5000000           mmap  front-coded-16-incremental        force  avgt    3   24.098 ±    1.876  ms/op
(giant union query)

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql       19           5000000           mmap                        none        false  avgt    3  567.362 ±  111.379  ms/op
SqlBenchmark.querySql       19           5000000           mmap               front-coded-4        false  avgt    3  641.548 ±   67.476  ms/op
SqlBenchmark.querySql       19           5000000           mmap              front-coded-16        false  avgt    3  602.931 ±   24.873  ms/op
SqlBenchmark.querySql       19           5000000           mmap   front-coded-4-incremental        false  avgt    3  593.706 ±   26.130  ms/op
SqlBenchmark.querySql       19           5000000           mmap  front-coded-16-incremental        false  avgt    3  440.288 ±   44.818  ms/op

SqlBenchmark.querySql       19           5000000           mmap                        none        force  avgt    3  378.028 ±   16.545  ms/op
SqlBenchmark.querySql       19           5000000           mmap               front-coded-4        force  avgt    3  495.283 ±   71.581  ms/op
SqlBenchmark.querySql       19           5000000           mmap              front-coded-16        force  avgt    3  428.606 ±   64.839  ms/op
SqlBenchmark.querySql       19           5000000           mmap   front-coded-4-incremental        force  avgt    3  429.358 ±   87.967  ms/op
SqlBenchmark.querySql       19           5000000           mmap  front-coded-16-incremental        force  avgt    3  349.346 ±   10.973  ms/op
SELECT dimSequential, dimZipf, SUM(sumLongSequential) FROM foo WHERE dimUniform NOT LIKE '%3' GROUP BY 1, 2

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt    Score      Error  Units
SqlBenchmark.querySql       21           5000000           mmap                        none        false  avgt    3  508.170 ±  299.396  ms/op
SqlBenchmark.querySql       21           5000000           mmap               front-coded-4        false  avgt    3  453.354 ±   42.640  ms/op
SqlBenchmark.querySql       21           5000000           mmap              front-coded-16        false  avgt    3  460.979 ±  122.715  ms/op
SqlBenchmark.querySql       21           5000000           mmap   front-coded-4-incremental        false  avgt    3  452.730 ±   32.584  ms/op
SqlBenchmark.querySql       21           5000000           mmap  front-coded-16-incremental        false  avgt    3  507.205 ±  343.754  ms/op

SqlBenchmark.querySql       21           5000000           mmap                        none        force  avgt    3  273.734 ±   78.223  ms/op
SqlBenchmark.querySql       21           5000000           mmap               front-coded-4        force  avgt    3  296.297 ±  127.980  ms/op
SqlBenchmark.querySql       21           5000000           mmap              front-coded-16        force  avgt    3  294.919 ±  237.858  ms/op
SqlBenchmark.querySql       21           5000000           mmap   front-coded-4-incremental        force  avgt    3  317.557 ±   56.171  ms/op
SqlBenchmark.querySql       21           5000000           mmap  front-coded-16-incremental        force  avgt    3  303.298 ±    7.330  ms/op
SELECT dimZipf, SUM(sumLongSequential) FROM foo WHERE dimSequential = '311' GROUP BY 1 ORDER BY 1

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt      Score        Error  Units
SqlBenchmark.querySql       22           5000000           mmap                        none        false  avgt    3     29.005 ±      0.359  ms/op
SqlBenchmark.querySql       22           5000000           mmap               front-coded-4        false  avgt    3     26.415 ±      0.986  ms/op
SqlBenchmark.querySql       22           5000000           mmap              front-coded-16        false  avgt    3     25.873 ±      1.919  ms/op
SqlBenchmark.querySql       22           5000000           mmap   front-coded-4-incremental        false  avgt    3     35.238 ±      3.281  ms/op
SqlBenchmark.querySql       22           5000000           mmap  front-coded-16-incremental        false  avgt    3     26.387 ±      3.763  ms/op

SqlBenchmark.querySql       22           5000000           mmap                        none        force  avgt    3     27.974 ±     15.065  ms/op
SqlBenchmark.querySql       22           5000000           mmap               front-coded-4        force  avgt    3     26.666 ±      7.790  ms/op
SqlBenchmark.querySql       22           5000000           mmap              front-coded-16        force  avgt    3     30.854 ±     23.258  ms/op
SqlBenchmark.querySql       22           5000000           mmap   front-coded-4-incremental        force  avgt    3     29.408 ±      0.818  ms/op
SqlBenchmark.querySql       22           5000000           mmap  front-coded-16-incremental        force  avgt    3     27.277 ±      0.355  ms/op
SELECT * FROM foo

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt      Score        Error  Units
SqlBenchmark.querySql       23           5000000           mmap                        none        false  avgt    3   9776.162 ±    252.465  ms/op
SqlBenchmark.querySql       23           5000000           mmap               front-coded-4        false  avgt    3  12116.736 ±    276.428  ms/op
SqlBenchmark.querySql       23           5000000           mmap              front-coded-16        false  avgt    3  12516.252 ±    221.973  ms/op
SqlBenchmark.querySql       23           5000000           mmap   front-coded-4-incremental        false  avgt    3   9325.666 ±    419.627  ms/op
SqlBenchmark.querySql       23           5000000           mmap  front-coded-16-incremental        false  avgt    3  12606.229 ±  20172.947  ms/op

SqlBenchmark.querySql       23           5000000           mmap                        none        force  avgt    3   9247.405 ±     73.372  ms/op
SqlBenchmark.querySql       23           5000000           mmap               front-coded-4        force  avgt    3  13036.321 ±  35385.557  ms/op
SqlBenchmark.querySql       23           5000000           mmap              front-coded-16        force  avgt    3  13370.692 ±  27603.658  ms/op
SqlBenchmark.querySql       23           5000000           mmap   front-coded-4-incremental        force  avgt    3   9285.215 ±    345.453  ms/op
SqlBenchmark.querySql       23           5000000           mmap  front-coded-16-incremental        force  avgt    3  11916.930 ±    364.104  ms/op
SELECT dimSequential, dimZipf, SUM(sumLongSequential)
FROM foo
WHERE dimSequential IN ('1', '2', '3', '4', '5', '10', '11', '20', '21', '23', '40', '50', '64', '70', '100') GROUP BY 1, 2

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt      Score        Error  Units
SqlBenchmark.querySql       26           5000000           mmap                        none        false  avgt    3     47.222 ±      1.082  ms/op
SqlBenchmark.querySql       26           5000000           mmap               front-coded-4        false  avgt    3     42.567 ±    186.693  ms/op
SqlBenchmark.querySql       26           5000000           mmap              front-coded-16        false  avgt    3     44.960 ±     37.589  ms/op
SqlBenchmark.querySql       26           5000000           mmap   front-coded-4-incremental        false  avgt    3     61.635 ±     54.484  ms/op
SqlBenchmark.querySql       26           5000000           mmap  front-coded-16-incremental        false  avgt    3     70.025 ±      2.339  ms/op

SqlBenchmark.querySql       26           5000000           mmap                        none        force  avgt    3     49.849 ±     55.976  ms/op
SqlBenchmark.querySql       26           5000000           mmap               front-coded-4        force  avgt    3     53.091 ±      8.129  ms/op
SqlBenchmark.querySql       26           5000000           mmap              front-coded-16        force  avgt    3     96.965 ±    193.393  ms/op
SqlBenchmark.querySql       26           5000000           mmap   front-coded-4-incremental        force  avgt    3     52.672 ±     16.071  ms/op
SqlBenchmark.querySql       26           5000000           mmap  front-coded-16-incremental        force  avgt    3     57.925 ±      2.672  ms/op
SELECT dimSequential, dimZipf, SUM(sumLongSequential) FROM foo WHERE dimSequential > '10' AND dimSequential < '8500' GROUP BY 1, 2

Benchmark              (query)  (rowsPerSegment)  (storageType)            (stringEncoding)  (vectorize)  Mode  Cnt      Score       Error  Units
SqlBenchmark.querySql       27           5000000           mmap                        none        false  avgt    3    400.771 ±   558.192  ms/op
SqlBenchmark.querySql       27           5000000           mmap               front-coded-4        false  avgt    3    385.736 ±   259.365  ms/op
SqlBenchmark.querySql       27           5000000           mmap              front-coded-16        false  avgt    3    395.724 ±   501.499  ms/op
SqlBenchmark.querySql       27           5000000           mmap   front-coded-4-incremental        false  avgt    3    406.457 ±   148.057  ms/op
SqlBenchmark.querySql       27           5000000           mmap  front-coded-16-incremental        false  avgt    3    480.617 ±    62.218  ms/op

SqlBenchmark.querySql       27           5000000           mmap                        none        force  avgt    3    244.646 ±    23.544  ms/op
SqlBenchmark.querySql       27           5000000           mmap               front-coded-4        force  avgt    3    246.913 ±    65.529  ms/op
SqlBenchmark.querySql       27           5000000           mmap              front-coded-16        force  avgt    3    249.113 ±    22.663  ms/op
SqlBenchmark.querySql       27           5000000           mmap   front-coded-4-incremental        force  avgt    3    245.034 ±   344.470  ms/op
SqlBenchmark.querySql       27           5000000           mmap  front-coded-16-incremental        force  avgt    3    249.513 ±   131.467  ms/op
Indexed direct measurements
Benchmark                                                   (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt     Score     Error  Units
FrontCodedIndexedBenchmark.get                                  generic          10000            10000       16  avgt    5    15.106 ±   0.082  ns/op
FrontCodedIndexedBenchmark.get                            front-coded-4          10000            10000       16  avgt    5    35.025 ±   0.153  ns/op
FrontCodedIndexedBenchmark.get                           front-coded-16          10000            10000       16  avgt    5    49.335 ±   0.521  ns/op
FrontCodedIndexedBenchmark.get        front-coded-incremental-buckets-4          10000            10000       16  avgt    5    32.442 ±   0.398  ns/op
FrontCodedIndexedBenchmark.get       front-coded-incremental-buckets-16          10000            10000       16  avgt    5    60.568 ±   0.420  ns/op
FrontCodedIndexedBenchmark.indexOf                              generic          10000            10000       16  avgt    5   140.989 ±   0.908  ns/op
FrontCodedIndexedBenchmark.indexOf                        front-coded-4          10000            10000       16  avgt    5   222.428 ±   1.258  ns/op
FrontCodedIndexedBenchmark.indexOf                       front-coded-16          10000            10000       16  avgt    5   255.546 ±   0.307  ns/op
FrontCodedIndexedBenchmark.indexOf    front-coded-incremental-buckets-4          10000            10000       16  avgt    5   286.266 ±   0.562  ns/op
FrontCodedIndexedBenchmark.indexOf   front-coded-incremental-buckets-16          10000            10000       16  avgt    5   249.843 ±   2.475  ns/op
FrontCodedIndexedBenchmark.iterator                             generic          10000            10000       16  avgt    5    30.963 ±  33.228  ns/op
FrontCodedIndexedBenchmark.iterator                       front-coded-4          10000            10000       16  avgt    5   169.666 ±  15.676  ns/op
FrontCodedIndexedBenchmark.iterator                      front-coded-16          10000            10000       16  avgt    5   210.420 ±  53.266  ns/op
FrontCodedIndexedBenchmark.iterator   front-coded-incremental-buckets-4          10000            10000       16  avgt    5    97.494 ±   7.658  ns/op
FrontCodedIndexedBenchmark.iterator  front-coded-incremental-buckets-16          10000            10000       16  avgt    5    56.607 ±  40.105  ns/op
Benchmark                                                   (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt     Score     Error  Units
FrontCodedIndexedBenchmark.get                                  generic         100000            10000       16  avgt    5    17.362 ±   3.500  ns/op
FrontCodedIndexedBenchmark.get                            front-coded-4         100000            10000       16  avgt    5    37.992 ±   0.256  ns/op
FrontCodedIndexedBenchmark.get                           front-coded-16         100000            10000       16  avgt    5    53.631 ±   0.362  ns/op
FrontCodedIndexedBenchmark.get        front-coded-incremental-buckets-4         100000            10000       16  avgt    5    35.996 ±   0.984  ns/op
FrontCodedIndexedBenchmark.get       front-coded-incremental-buckets-16         100000            10000       16  avgt    5    68.245 ±   0.842  ns/op
FrontCodedIndexedBenchmark.indexOf                              generic         100000            10000       16  avgt    5   207.536 ±   2.531  ns/op
FrontCodedIndexedBenchmark.indexOf                        front-coded-4         100000            10000       16  avgt    5   289.569 ±  12.664  ns/op
FrontCodedIndexedBenchmark.indexOf                       front-coded-16         100000            10000       16  avgt    5   290.369 ±   2.343  ns/op
FrontCodedIndexedBenchmark.indexOf    front-coded-incremental-buckets-4         100000            10000       16  avgt    5   254.980 ±   8.136  ns/op
FrontCodedIndexedBenchmark.indexOf   front-coded-incremental-buckets-16         100000            10000       16  avgt    5   292.639 ±   2.773  ns/op
FrontCodedIndexedBenchmark.iterator                             generic         100000            10000       16  avgt    5   273.635 ±   4.156  ns/op
FrontCodedIndexedBenchmark.iterator                       front-coded-4         100000            10000       16  avgt    5  1929.693 ± 117.850  ns/op
FrontCodedIndexedBenchmark.iterator                      front-coded-16         100000            10000       16  avgt    5   897.824 ±  66.585  ns/op
FrontCodedIndexedBenchmark.iterator   front-coded-incremental-buckets-4         100000            10000       16  avgt    5  1376.505 ±  56.817  ns/op
FrontCodedIndexedBenchmark.iterator  front-coded-incremental-buckets-16         100000            10000       16  avgt    5  1013.401 ± 195.662  ns/op
Benchmark                                                                (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt         Score      Error  Units
FrontCodedIndexedBenchmark.get                                               generic        1000000            10000       16  avgt    5        17.893 ±    0.280  ns/op
FrontCodedIndexedBenchmark.get                                         front-coded-4        1000000            10000       16  avgt    5        41.075 ±    0.569  ns/op
FrontCodedIndexedBenchmark.get                                        front-coded-16        1000000            10000       16  avgt    5        57.116 ±    0.489  ns/op
FrontCodedIndexedBenchmark.get                     front-coded-incremental-buckets-4        1000000            10000       16  avgt    5        42.678 ±    1.104  ns/op
FrontCodedIndexedBenchmark.get                    front-coded-incremental-buckets-16        1000000            10000       16  avgt    5        76.118 ±    0.796  ns/op
FrontCodedIndexedBenchmark.indexOf                                           generic        1000000            10000       16  avgt    5       387.043 ±    6.064  ns/op
FrontCodedIndexedBenchmark.indexOf                                     front-coded-4        1000000            10000       16  avgt    5       442.987 ±    9.478  ns/op
FrontCodedIndexedBenchmark.indexOf                                    front-coded-16        1000000            10000       16  avgt    5       452.009 ±   10.927  ns/op
FrontCodedIndexedBenchmark.indexOf                 front-coded-incremental-buckets-4        1000000            10000       16  avgt    5       446.948 ±    1.637  ns/op
FrontCodedIndexedBenchmark.indexOf                front-coded-incremental-buckets-16        1000000            10000       16  avgt    5       447.710 ±   10.167  ns/op
FrontCodedIndexedBenchmark.iterator                                          generic        1000000            10000       16  avgt    5      2664.274 ±   20.073  ns/op
FrontCodedIndexedBenchmark.iterator                                    front-coded-4        1000000            10000       16  avgt    5     16395.276 ± 2551.406  ns/op
FrontCodedIndexedBenchmark.iterator                                   front-coded-16        1000000            10000       16  avgt    5      7731.031 ±  611.981  ns/op
FrontCodedIndexedBenchmark.iterator                front-coded-incremental-buckets-4        1000000            10000       16  avgt    5      5263.330 ±   47.130  ns/op
FrontCodedIndexedBenchmark.iterator               front-coded-incremental-buckets-16        1000000            10000       16  avgt    5      6737.476 ±  562.373  ns/op
Indexed sizes
Benchmark                                                                (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt        Score     Error  Units
FrontCodedIndexedBenchmark.get:encoded size                                  generic          10000            10000       16  avgt    5   240010.000            bytes
FrontCodedIndexedBenchmark.get:encoded size                            front-coded-4          10000            10000       16  avgt    5   169861.000            bytes
FrontCodedIndexedBenchmark.get:encoded size                           front-coded-16          10000            10000       16  avgt    5   164319.000            bytes
FrontCodedIndexedBenchmark.get:encoded size        front-coded-incremental-buckets-4          10000            10000       16  avgt    5   167499.000            bytes
FrontCodedIndexedBenchmark.get:encoded size       front-coded-incremental-buckets-16          10000            10000       16  avgt    5   156734.000            bytes
Benchmark                                                                (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt        Score     Error  Units
FrontCodedIndexedBenchmark.get:encoded size                                  generic         100000            10000       16  avgt    5  2400010.000            bytes
FrontCodedIndexedBenchmark.get:encoded size                            front-coded-4         100000            10000       16  avgt    5  1636743.000            bytes
FrontCodedIndexedBenchmark.get:encoded size                           front-coded-16         100000            10000       16  avgt    5  1564884.000            bytes
FrontCodedIndexedBenchmark.get:encoded size        front-coded-incremental-buckets-4         100000            10000       16  avgt    5  1612881.000            bytes
FrontCodedIndexedBenchmark.get:encoded size       front-coded-incremental-buckets-16         100000            10000       16  avgt    5  1491357.000            bytes
Benchmark                                                                (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt         Score      Error  Units
FrontCodedIndexedBenchmark.get:encoded size                                  generic        1000000            10000       16  avgt    5  24000010.000             bytes
FrontCodedIndexedBenchmark.get:encoded size                            front-coded-4        1000000            10000       16  avgt    5  15729053.000             bytes
FrontCodedIndexedBenchmark.get:encoded size                           front-coded-16        1000000            10000       16  avgt    5  14912643.000             bytes
FrontCodedIndexedBenchmark.get:encoded size        front-coded-incremental-buckets-4        1000000            10000       16  avgt    5  15512437.000             bytes
FrontCodedIndexedBenchmark.get:encoded size       front-coded-incremental-buckets-16        1000000            10000       16  avgt    5  14140634.000             bytes

Key changed/added classes in this PR
  • FrontCodedIndexedWriter
  • FrontCodedIndexed
  • StringEncodingStrategy

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • been tested in a test Druid cluster.

@clintropolis
Copy link
Member Author

clintropolis commented Feb 27, 2023

I marked this PR WIP since I'm still working on improving the performance of get, which is currently reading every value when seeking a particular value because it was the easiest way to get things working correctly, but I think I can do better by keeping a stack of prefix lengths and buffer positions and working my way backwards to fill the value buffer. Current benchmarks (which really aren't terrible):

Benchmark                                                                (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt        Score    Error  Units
FrontCodedIndexedBenchmark.get                                               generic          10000            10000       16  avgt    5       15.300 ±  0.077  ns/op
FrontCodedIndexedBenchmark.get                                               generic         100000            10000       16  avgt    5       16.860 ±  0.036  ns/op
FrontCodedIndexedBenchmark.get                                         front-coded-4          10000            10000       16  avgt    5       35.312 ±  0.059  ns/op
FrontCodedIndexedBenchmark.get                                         front-coded-4         100000            10000       16  avgt    5       38.921 ±  0.817  ns/op
FrontCodedIndexedBenchmark.get                                        front-coded-16          10000            10000       16  avgt    5       49.355 ±  0.301  ns/op
FrontCodedIndexedBenchmark.get                                        front-coded-16         100000            10000       16  avgt    5       53.588 ±  0.149  ns/op
FrontCodedIndexedBenchmark.get                     front-coded-incremental-buckets-4          10000            10000       16  avgt    5       44.787 ±  0.825  ns/op
FrontCodedIndexedBenchmark.get                     front-coded-incremental-buckets-4         100000            10000       16  avgt    5       62.222 ±  7.047  ns/op
FrontCodedIndexedBenchmark.get                    front-coded-incremental-buckets-16          10000            10000       16  avgt    5      113.985 ±  0.302  ns/op
FrontCodedIndexedBenchmark.get                    front-coded-incremental-buckets-16         100000            10000       16  avgt    5      143.425 ±  0.562  ns/op
FrontCodedIndexedBenchmark.indexOf                                           generic          10000            10000       16  avgt    5      147.326 ±  0.472  ns/op
FrontCodedIndexedBenchmark.indexOf                                           generic         100000            10000       16  avgt    5      214.154 ±  9.449  ns/op
FrontCodedIndexedBenchmark.indexOf                                     front-coded-4          10000            10000       16  avgt    5      267.560 ±  1.318  ns/op
FrontCodedIndexedBenchmark.indexOf                                     front-coded-4         100000            10000       16  avgt    5      260.044 ± 13.423  ns/op
FrontCodedIndexedBenchmark.indexOf                                    front-coded-16          10000            10000       16  avgt    5      281.611 ±  1.649  ns/op
FrontCodedIndexedBenchmark.indexOf                                    front-coded-16         100000            10000       16  avgt    5      321.547 ±  2.826  ns/op
FrontCodedIndexedBenchmark.indexOf                 front-coded-incremental-buckets-4          10000            10000       16  avgt    5      265.893 ± 22.296  ns/op
FrontCodedIndexedBenchmark.indexOf                 front-coded-incremental-buckets-4         100000            10000       16  avgt    5      300.960 ± 27.500  ns/op
FrontCodedIndexedBenchmark.indexOf                front-coded-incremental-buckets-16          10000            10000       16  avgt    5      250.964 ±  2.252  ns/op
FrontCodedIndexedBenchmark.indexOf                front-coded-incremental-buckets-16         100000            10000       16  avgt    5      317.990 ±  1.194  ns/op
FrontCodedIndexedBenchmark.iterator                                          generic          10000            10000       16  avgt    5       26.014 ±  0.062  ns/op
FrontCodedIndexedBenchmark.iterator                                          generic         100000            10000       16  avgt    5      267.468 ±  1.349  ns/op
FrontCodedIndexedBenchmark.iterator                                    front-coded-4          10000            10000       16  avgt    5       89.531 ±  4.409  ns/op
FrontCodedIndexedBenchmark.iterator                                    front-coded-4         100000            10000       16  avgt    5     1007.466 ± 42.022  ns/op
FrontCodedIndexedBenchmark.iterator                                   front-coded-16          10000            10000       16  avgt    5       63.249 ±  2.705  ns/op
FrontCodedIndexedBenchmark.iterator                                   front-coded-16         100000            10000       16  avgt    5      628.595 ± 35.804  ns/op
FrontCodedIndexedBenchmark.iterator                front-coded-incremental-buckets-4          10000            10000       16  avgt    5       81.262 ±  3.462  ns/op
FrontCodedIndexedBenchmark.iterator                front-coded-incremental-buckets-4         100000            10000       16  avgt    5      570.711 ± 14.082  ns/op
FrontCodedIndexedBenchmark.iterator               front-coded-incremental-buckets-16          10000            10000       16  avgt    5       49.487 ± 20.310  ns/op
FrontCodedIndexedBenchmark.iterator               front-coded-incremental-buckets-16         100000            10000       16  avgt    5      509.281 ±  7.377  ns/op

sizes:

FrontCodedIndexedBenchmark.get:encoded size                                  generic          10000            10000       16  avgt    5   240010.000           bytes
FrontCodedIndexedBenchmark.get:encoded size                                  generic         100000            10000       16  avgt    5  2400010.000           bytes
FrontCodedIndexedBenchmark.get:encoded size                            front-coded-4          10000            10000       16  avgt    5   169907.000           bytes
FrontCodedIndexedBenchmark.get:encoded size                            front-coded-4         100000            10000       16  avgt    5  1636647.000           bytes
FrontCodedIndexedBenchmark.get:encoded size                           front-coded-16          10000            10000       16  avgt    5   164100.000           bytes
FrontCodedIndexedBenchmark.get:encoded size                           front-coded-16         100000            10000       16  avgt    5  1564982.000           bytes
FrontCodedIndexedBenchmark.get:encoded size        front-coded-incremental-buckets-4          10000            10000       16  avgt    5   167426.000           bytes
FrontCodedIndexedBenchmark.get:encoded size        front-coded-incremental-buckets-4         100000            10000       16  avgt    5  1612792.000           bytes
FrontCodedIndexedBenchmark.get:encoded size       front-coded-incremental-buckets-16          10000            10000       16  avgt    5   156782.000           bytes
FrontCodedIndexedBenchmark.get:encoded size       front-coded-incremental-buckets-16         100000            10000       16  avgt    5  1491159.000           bytes

with wikipedia:
Screenshot 2023-02-27 at 1 36 57 AM

changes:
* Adds 'useIncrementalBuckets' option to 'frontCoded' string encoding strategy, which when set is fed to FrontCodedIndexedWriter when true writes out a v1 FrontCodedIndexed which stores buckets on a prefix of the previous value instead of the first value in the bucket
* Default for 'useIncrementalBuckets' is set to true
* Update tests to test both modes
@clintropolis clintropolis force-pushed the front-coded-incremental-buckets branch from 29aab3f to 4efbfdc Compare February 27, 2023 10:31
smooshDirGeneric = FileUtils.createTempDir();
fileGeneric = File.createTempFile("genericIndexedBenchmark", "meta");

smooshDirFrontCodedIncrementalBuckets = FileUtils.createTempDir();
fileFrontCodedIncrementalBuckets = File.createTempFile("frontCodedIndexedBenchmarkIncrementalBuckets", "meta");

Check warning

Code scanning / CodeQL

Local information disclosure in a temporary directory

Local information disclosure vulnerability due to use of file readable by other local users.
@clintropolis
Copy link
Member Author

getting closer 🚀

Benchmark                                               (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt        Score    Error  Units
FrontCodedIndexedBenchmark.get                              generic          10000            10000       16  avgt    5       15.014 ±  0.124  ns/op
FrontCodedIndexedBenchmark.get                              generic         100000            10000       16  avgt    5       16.732 ±  0.103  ns/op
FrontCodedIndexedBenchmark.get                        front-coded-4          10000            10000       16  avgt    5       35.320 ±  0.111  ns/op
FrontCodedIndexedBenchmark.get                        front-coded-4         100000            10000       16  avgt    5       37.815 ±  0.395  ns/op
FrontCodedIndexedBenchmark.get                       front-coded-16          10000            10000       16  avgt    5       48.906 ±  0.504  ns/op
FrontCodedIndexedBenchmark.get                       front-coded-16         100000            10000       16  avgt    5       53.503 ±  0.686  ns/op
FrontCodedIndexedBenchmark.get    front-coded-incremental-buckets-4          10000            10000       16  avgt    5       32.281 ±  0.371  ns/op
FrontCodedIndexedBenchmark.get    front-coded-incremental-buckets-4         100000            10000       16  avgt    5       36.480 ±  0.309  ns/op
FrontCodedIndexedBenchmark.get   front-coded-incremental-buckets-16          10000            10000       16  avgt    5       64.621 ±  1.073  ns/op
FrontCodedIndexedBenchmark.get   front-coded-incremental-buckets-16         100000            10000       16  avgt    5       73.794 ± 15.222  ns/op

bucket size of 4 seems equivalent (or faster?), bucket size of 16 is ~15-20ns slower which is maybe ok given that it can be a lot more effective...

@clintropolis
Copy link
Member Author

slightly better by returning the values with prefix 0 directly:

Benchmark                                              (indexType)  (numElements)  (numOperations)  (width)  Mode  Cnt   Score   Error  Units
FrontCodedIndexedBenchmark.get                             generic          10000            10000       16  avgt    5  15.716 ± 0.072  ns/op
FrontCodedIndexedBenchmark.get                             generic         100000            10000       16  avgt    5  16.774 ± 0.123  ns/op
FrontCodedIndexedBenchmark.get                       front-coded-4          10000            10000       16  avgt    5  35.673 ± 0.290  ns/op
FrontCodedIndexedBenchmark.get                       front-coded-4         100000            10000       16  avgt    5  38.154 ± 0.456  ns/op
FrontCodedIndexedBenchmark.get                      front-coded-16          10000            10000       16  avgt    5  48.718 ± 0.163  ns/op
FrontCodedIndexedBenchmark.get                      front-coded-16         100000            10000       16  avgt    5  53.583 ± 0.666  ns/op
FrontCodedIndexedBenchmark.get   front-coded-incremental-buckets-4          10000            10000       16  avgt    5  30.538 ± 0.611  ns/op
FrontCodedIndexedBenchmark.get   front-coded-incremental-buckets-4         100000            10000       16  avgt    5  34.603 ± 0.257  ns/op
FrontCodedIndexedBenchmark.get  front-coded-incremental-buckets-16          10000            10000       16  avgt    5  63.026 ± 0.594  ns/op
FrontCodedIndexedBenchmark.get  front-coded-incremental-buckets-16         100000            10000       16  avgt    5  70.225 ± 1.225  ns/op

@clintropolis clintropolis removed the WIP label Mar 2, 2023
@clintropolis
Copy link
Member Author

Should something be added here: https://github.com/apache/druid/blob/master/web-console/src/druid-models/index-spec/index-spec.tsx#L28 here https://github.com/apache/druid/blob/master/web-console/src/druid-models/index-spec/index-spec.tsx#L48 and here https://github.com/apache/druid/blob/master/web-console/src/druid-models/index-spec/index-spec.tsx#L97 ? Or do you want to do that in a follow on PR?

The numbers for v1 seem nice enough that I'm considering just removing the option to write v0, which means no changes required here, so lets hold off until I decide for sure on that.

@clintropolis
Copy link
Member Author

the numbers on v1 look good enough to me to remove the new option for writing v0 in favor of always writing v1, will update the PR description

@clintropolis clintropolis changed the title add an "incremental" buckets option to FrontCodedIndexed improvements to FrontCodedIndexed - bump to V1 Mar 9, 2023
@clintropolis clintropolis changed the title improvements to FrontCodedIndexed - bump to V1 better FrontCodedIndexed Mar 9, 2023
Copy link
Contributor

@gianm gianm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and I also agree we should always write out incremental buckets.

@gianm
Copy link
Contributor

gianm commented Mar 13, 2023

What are your thoughts on when front-coded should be the default encoding?

Comment on lines +548 to +553
* This method uses this shared prefix length to skip more expensive byte by byte full value comparisons when
* possible by comparing the shared prefix length with the prefix length of the fragment. Since the bucket is always
* sorted, prefix lengths shrink as you progress to higher indexes, and we can use this to reason that a fragment
* with a longer prefix length than the shared prefix will always sort before the value we are looking for, and values
* which have a shorter prefix will always be greater than the value we are looking for, so we only need to do a
* full comparison if the prefix length is the same
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, this javadoc needs adjusted, but i will just do this on a later PR

@clintropolis clintropolis merged commit ed57c5c into apache:master Mar 15, 2023
@clintropolis clintropolis deleted the front-coded-incremental-buckets branch March 15, 2023 01:14
@clintropolis
Copy link
Member Author

What are your thoughts on when front-coded should be the default encoding?

Unfortunately I think since I just bumped the version of this thing, at earliest it could be the version after the next release to make rollback to the previous version an option when upgrading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants