packages feed

double-conversion 2.0.4.1 → 2.0.4.2

raw patch · 11 files changed

+288/−61 lines, 11 filesdep +system-cxx-std-libdep ~basedep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: system-cxx-std-lib

Dependency ranges changed: base, bytestring

API changes (from Hackage documentation)

Files

Data/Double/Conversion/ByteString.hs view
@@ -11,6 +11,9 @@ -- in new projects.  -- Please, use Convertable type class from Data.Double.Conversion.Convertable -- +-- It is espesially recommended to convert a large amount of numbers via bytestring builder+-- using methods of Convertable type class. It is about 10-15x faster. +--  -- Fast, efficient support for converting between double precision -- floating point values and text. --
Data/Double/Conversion/Convertable.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE DefaultSignatures, InstanceSigs, MagicHash, MultiParamTypeClasses,-             TypeFamilies #-}+             TypeFamilies, TypeOperators #-}  -- | -- Module      : Data.Double.Conversion.Convertable@@ -27,7 +27,7 @@ import qualified Data.Double.Conversion.Internal.TextBuilder as CTB (convert) import qualified Data.Text.Internal.Builder as T (Builder) --- | Type class for floating data types, that cen be converted, using double-conversion library+-- | Type class for floating data types, that can be converted, using double-conversion library -- -- Default instanced convert input to Double and then make Bytestring Builder from it. --@@ -51,11 +51,15 @@ -- Compute the shortest string of digits that correctly represent -- the input number. ----- Conversion to text is twice faster than conversion to bytestring -- Conversion to text via Builder (both in the in case of bytestring and text) in case of single number--- is much slower, than to text or bytestring directly. (2-3x)--- But conversion large amount of numbers to text via Builder is much faster than directly (up to 50x).--- Conversion to text via text builder is a little slower, then via bytestring builder+-- is a bit slower, than to text or bytestring directly.+-- But conversion a large amount of numbers to text via Builder (for example using foldr) is much faster than direct conversion to Text (up to 10-15x).+--+-- The same works for bytestrings: conversion, for example, a list of 20000 doubles to bytestring builder +-- and then to bytestring is about 13 times faster than direct conversion of this list to bytestring. +--+-- Conversion to text via text builder is a little bit slower, than conversion to bytestring via bytestring builder. +  class (RealFloat a, IsString b) => Convertable a b where   toExponential :: Int -> a -> b
Data/Double/Conversion/Internal/ByteString.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeFamilies, TypeOperators #-}  -- | -- Module      : Data.Double.Conversion.ByteString
Data/Double/Conversion/Internal/ByteStringBuilder.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeFamilies, TypeOperators #-}  -- | -- Module      : Data.Double.Conversion.ByteStringBuilder@@ -11,9 +11,6 @@ -- -- Fast, efficient support for converting between double precision -- floating point values and bytestring builder.---- This functions are much slower on the single value, but also it is much faster in conversting big set of--- numbers, than bytestring functions. See benchmark.  module Data.Double.Conversion.Internal.ByteStringBuilder     (convert
Data/Double/Conversion/Internal/Text.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies, BangPatterns #-}+{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies, BangPatterns, TypeOperators #-}  -- | -- Module      : Data.Double.Conversion.Text@@ -52,7 +52,7 @@ #endif       size <- unsafeIOToST $ act (realToFrac val) ma       when (size == -1) .-        fail $ "Data.Double.Conversion.Text." ++ func +++        error $ "Data.Double.Conversion.Text." ++ func ++                ": conversion failed (invalid precision requested)"       frozen <- A.unsafeFreeze buf       return $ Text frozen 0 (fromIntegral size)
Data/Double/Conversion/Internal/TextBuilder.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies #-}+{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies, TypeOperators #-} -- | -- Module      : Data.Double.Conversion.TextBuilder -- Copyright   : (c) 2011 MailRank, Inc.@@ -28,21 +28,27 @@ import Data.Text.Internal.Builder (Builder, writeN) import Foreign.C.Types (CDouble, CFloat, CInt) import GHC.Prim (MutableByteArray#)+import Control.Monad.ST (runST) --- | Not implemented yet  convert :: (RealFloat a, RealFloat b, b ~ ForeignFloating a) => String -> CInt         -> (forall s. b -> MutableByteArray# s -> IO CInt)         -> a -> Builder {-# SPECIALIZE convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Builder #-} {-# SPECIALIZE convert :: String -> CInt -> (forall s. CFloat -> MutableByteArray# s -> IO CInt) -> Float -> Builder #-} {-# INLINABLE convert #-}+convert func len act val = runST $ do  #if MIN_VERSION_text(2,0,0)-convert func len act val = writeN (fromIntegral len) $ \(A.MutableByteArray maBa) _ -> do+  mTempArr@(A.MutableByteArray tempMArr) <- A.new (fromIntegral len) #else-convert func len act val = writeN (fromIntegral len) $ \(A.MArray maBa) _ -> do+  mTempArr@(A.MArray tempMArr) <- A.new (fromIntegral len) #endif-    size <- unsafeIOToST $ act (realToFrac val) maBa-    when (size == -1) .-        fail $ "Data.Double.Conversion.Text." ++ func ++-               ": conversion failed (invalid precision requested)"-    return ()+  size <- unsafeIOToST $ act (realToFrac val) tempMArr+  tempArr <- A.unsafeFreeze mTempArr+  when (size == -1) .+      error $ "Data.Double.Conversion.Text." ++ func +++              ": conversion failed."+#if MIN_VERSION_text(2,0,0)+  return $ writeN (fromIntegral size) $ \mArr _ -> A.copyI (fromIntegral size) mArr 0 tempArr 0+#else+  return $ writeN (fromIntegral size) $ \mArr _ -> A.copyI mArr 0 tempArr 0 (fromIntegral size)+#endif
Data/Double/Conversion/Text.hs view
@@ -13,6 +13,9 @@ -- in new projects.  -- Please, use Convertable type class from Data.Double.Conversion.Convertable --+-- It is espesially recommended to convert a large amount of numbers via text builder+-- using methods of Convertable type class. It is about 10-15x faster.+--  -- Fast, efficient support for converting between double precision -- floating point values and text. --
benchmarks/Benchmarks.hs view
@@ -18,34 +18,34 @@ testFloatList = [2.08345919 .. 20002.08345919] :: [Float]  testListBSBuilder :: (Double -> BB.Builder) -> [Double] -> BSS.ByteString-testListBSBuilder func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x) <> y) mempty list+testListBSBuilder func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x <> ", ") <> y) mempty list  testListBSBuilderFloat :: (Float -> BB.Builder) -> [Float] -> BSS.ByteString-testListBSBuilderFloat func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x) <> y) mempty list+testListBSBuilderFloat func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x <> ", ") <> y) mempty list  testListByteString :: (Double -> BSS.ByteString) -> [Double] -> BSS.ByteString-testListByteString func = foldr (\x y -> (func x) <> y) mempty+testListByteString func = foldr (\x y -> (func x <> ", ") <> y) mempty  testListByteStringFloat :: (Float -> BSS.ByteString) -> [Float] -> BSS.ByteString-testListByteStringFloat func = foldr (\x y -> (func x) <> y) mempty+testListByteStringFloat func = foldr (\x y -> (func x <> ", ") <> y) mempty  testListText :: (Double -> T.Text) -> [Double] -> T.Text-testListText func = foldr (\x y -> (func x) <> y) mempty+testListText func = foldr (\x y -> (func x <> ", ") <> y) mempty  testListTextFloat :: (Float -> T.Text) -> [Float] -> T.Text-testListTextFloat func = foldr (\x y -> (func x) <> y) mempty+testListTextFloat func = foldr (\x y -> (func x <> ", ") <> y) mempty  testListTextBuilder :: (Double -> BT.Builder) -> [Double] -> T.Text-testListTextBuilder func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x) <> y) mempty list+testListTextBuilder func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x <> ", ") <> y) mempty list  testListTextBuilderFloat :: (Float -> BT.Builder) -> [Float] -> T.Text-testListTextBuilderFloat func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x) <> y) mempty list+testListTextBuilderFloat func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x <> ", ") <> y) mempty list  testFuncBuilderDefault :: [Double] -> BSS.ByteString-testFuncBuilderDefault = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.doubleDec x) <> y) mempty list+testFuncBuilderDefault = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.doubleDec x <> ", ") <> y) mempty list  testFuncBuilderDefaultFloat :: [Float] -> BSS.ByteString-testFuncBuilderDefaultFloat = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.floatDec x) <> y) mempty list+testFuncBuilderDefaultFloat = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.floatDec x <> ", ") <> y) mempty list   main = defaultMain [
+ cbits/hs-double-conversion-embed.cc view
@@ -0,0 +1,199 @@+#include "double-conversion.h"+#include "hs-double-conversion.h"+#include <stdio.h>++using namespace double_conversion;++static const int kToShortestLength = 26;++extern "C"+int _hs_ToShortestLength(void)+{+  return kToShortestLength;+}++static const int kToFixedLength =+  1 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint ++  1 + DoubleToStringConverter::kMaxFixedDigitsAfterPoint;++extern "C"+int _hs_ToFixedLength(void)+{+  return kToFixedLength;+}++static const int kToExponentialLength =+  DoubleToStringConverter::kMaxExponentialDigits + 8;++extern "C"+int _hs_ToExponentialLength(void)+{+  return kToExponentialLength;+}++static const int kToPrecisionLength =+  DoubleToStringConverter::kMaxPrecisionDigits + 7;++extern "C"+int _hs_ToPrecisionLength(void)+{+  return kToPrecisionLength;+}++static int copy(uint16_t *buf, const StringBuilder& builder, const char *cbuf)+{+  const int pos = builder.position();+  for (int i = 0; i < pos; i++)+    buf[i] = cbuf[i];+  return pos;+}++static int copy(uint16_t *buf, const char *cbuf, const int len)+{+  for (int i = 0; i < len; i++)+    buf[i] = cbuf[i];+  return len;+}++static inline const DoubleToStringConverter& defaultConverter(void)+{+  const int flags = DoubleToStringConverter::UNIQUE_ZERO;+  static DoubleToStringConverter converter(flags,+                                           "Infinity",+                                           "NaN",+                                           'e',+                                           -6, 21,+                                           6, 0);+  return converter;+}++static inline const DoubleToStringConverter& floatConverter(void)+{+  const int flags = DoubleToStringConverter::UNIQUE_ZERO;+  static DoubleToStringConverter converter(flags,+                                           "Infinity",+                                           "NaN",+                                           'e',+                                           -6, 6,+                                           6, 0);+  return converter;+}++extern "C"+int _hs_ToShortest(double value, char *buf)+{+  StringBuilder builder(buf, kToShortestLength);+  return defaultConverter().ToShortest(value, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_ToShortestFloat(float value, char *buf)+{+  StringBuilder builder(buf, kToShortestLength);+  return floatConverter().ToShortestSingle(value, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_Text_ToShortest(double value, uint16_t *buf)+{+  char cbuf[kToShortestLength];+  return copy(buf, cbuf, _hs_ToShortest(value, cbuf));+}++extern "C"+int _hs_Text_ToShortestFloat(float value, uint16_t *buf)+{+  char cbuf[kToShortestLength];+  return copy(buf, cbuf, _hs_ToShortestFloat(value, cbuf));+}++extern "C"+int _hs_ToFixed(double value, char *buf, const int ndigits)+{+  StringBuilder builder(buf, kToFixedLength);+  return defaultConverter().ToFixed(value, ndigits, &builder)+    ? builder.position() : -1;+}++int _hs_ToFixedFloat(float value, char *buf, const int ndigits)+{+  StringBuilder builder(buf, kToFixedLength);+  return floatConverter().ToFixed(value, ndigits, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_Text_ToFixed(double value, uint16_t *buf, const int ndigits)+{+  char cbuf[kToFixedLength];+  return copy(buf, cbuf, _hs_ToFixed(value, cbuf, ndigits));+}++extern "C"+int _hs_Text_ToFixedFloat(float value, uint16_t *buf, const int ndigits)+{+  char cbuf[kToFixedLength];+  return copy(buf, cbuf, _hs_ToFixedFloat(value, cbuf, ndigits));+}++extern "C"+int _hs_ToExponential(double value, char *buf, const int ndigits)+{+  StringBuilder builder(buf, kToExponentialLength);+  return defaultConverter().ToExponential(value, ndigits, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_ToExponentialFloat(float value, char *buf, const int ndigits)+{+  StringBuilder builder(buf, kToExponentialLength);+  return floatConverter().ToExponential(value, ndigits, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_Text_ToExponential(double value, uint16_t *buf, const int ndigits)+{+  char cbuf[kToExponentialLength];+  return copy(buf, cbuf, _hs_ToExponential(value, cbuf, ndigits));+}++extern "C"+int _hs_Text_ToExponentialFloat(float value, uint16_t *buf, const int ndigits)+{+  char cbuf[kToExponentialLength];+  return copy(buf, cbuf, _hs_ToExponentialFloat(value, cbuf, ndigits));+}++extern "C"+int _hs_ToPrecision(double value, char *buf, const int precision)+{+  StringBuilder builder(buf, kToPrecisionLength);+  return defaultConverter().ToPrecision(value, precision, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_ToPrecisionFloat(float value, char *buf, const int precision)+{+  StringBuilder builder(buf, kToPrecisionLength);+  return floatConverter().ToPrecision(value, precision, &builder)+    ? builder.position() : -1;+}++extern "C"+int _hs_Text_ToPrecision(double value, uint16_t *buf, const int precision)+{+  char cbuf[kToPrecisionLength];+  return copy(buf, cbuf, _hs_ToPrecision(value, cbuf, precision));+}++extern "C"+int _hs_Text_ToPrecisionFloat(float value, uint16_t *buf, const int precision)+{+  char cbuf[kToPrecisionLength];+  return copy(buf, cbuf, _hs_ToPrecisionFloat(value, cbuf, precision));+}
cbits/hs-double-conversion.cc view
@@ -1,4 +1,4 @@-#include "double-conversion.h"+#include "double-conversion/double-conversion.h" #include "hs-double-conversion.h" #include <stdio.h> 
double-conversion.cabal view
@@ -1,15 +1,15 @@+cabal-version:  2.2 name:           double-conversion-version:        2.0.4.1-license:        BSD3+version:        2.0.4.2+license:        BSD-3-Clause license-file:   LICENSE-homepage:       https://github.com/Haskell-mouse/double-conversion-bug-reports:    https://github.com/Haskell-mouse/double-conversion/issues+homepage:       https://github.com/haskell/double-conversion+bug-reports:    https://github.com/haskell/double-conversion/issues category:       Text author:         Bryan O'Sullivan <bos@serpentine.com> maintainer:     Bryan O'Sullivan <bos@serpentine.com> stability:      experimental synopsis:       Fast conversion between single and double precision floating point and text-cabal-version:  >= 1.10 build-type:     Simple description:     A library that performs fast, accurate conversion between @@ -25,12 +25,11 @@     The 'Text' versions of these functions are about 30 times faster     than the default 'show' implementation for the 'Double' type.     .-    The 'ByteString' versions are /slower/ than the 'Text' versions;-    roughly half the speed.  (This seems to be due to the cost of-    allocating 'ByteString' values via @malloc@.)+    The 'ByteString' versions are have very close speed to the 'Text' versions;     .-    Builder versions are slower on single value, but they are much faster on large number of values -    (up to 50x faster on list with 20000 doubles).  +    Builder versions (both for Text and Bytestring) are slower on single value,+    but they are much faster on large number of values +    (up to 20x faster on list with 20000 doubles).     .     As a final note, be aware that the @bytestring-show@ package is     about 50% slower than simply using 'show'.@@ -65,31 +64,47 @@   default: False   manual: True +flag embedded_double_conversion+  description: embed the C++ double_conversion library+  default: True+ library-  c-sources:-    cbits/hs-double-conversion.cc-    double-conversion/src/bignum.cc-    double-conversion/src/bignum-dtoa.cc-    double-conversion/src/cached-powers.cc-    double-conversion/src/diy-fp.cc-    double-conversion/src/double-conversion.cc-    double-conversion/src/fast-dtoa.cc-    double-conversion/src/fixed-dtoa.cc-    double-conversion/src/strtod.cc+  if impl(ghc >= 9.4)+    build-depends: system-cxx-std-lib == 1.0 -  if os(windows)-    if arch(x86_64)+  elif os(darwin) || os(freebsd)+    extra-libraries: c+++  elif os(windows)+    if arch(x86_64) && impl(ghc < 8.6.5)       extra-libraries: stdc++-6 gcc_s_seh-1-    else+    elif arch(x86_64)+      extra-libraries: stdc++ gcc_s_seh-1+    elif impl(ghc >= 8.6.5)+      extra-libraries: stdc++ gcc_s_dw2-1+    else        extra-libraries: stdc++-6 gcc_s_dw2-1   else-    if os(darwin)-      extra-libraries: c++-    else-      extra-libraries: stdc+++    extra-libraries: stdc++ +  if flag(embedded_double_conversion)+    c-sources:+      cbits/hs-double-conversion-embed.cc++      double-conversion/src/bignum.cc+      double-conversion/src/bignum-dtoa.cc+      double-conversion/src/cached-powers.cc+      double-conversion/src/diy-fp.cc+      double-conversion/src/double-conversion.cc+      double-conversion/src/fast-dtoa.cc+      double-conversion/src/fixed-dtoa.cc+      double-conversion/src/strtod.cc+    include-dirs: double-conversion/src+  else+    extra-libraries: double-conversion+    c-sources:+      cbits/hs-double-conversion.cc+   include-dirs:-    double-conversion/src     include    exposed-modules: