Ayrat
Понимаешь!
Romɑn
https://gist.github.com/AlexeyRaga/9825fb67e0a926005d72032e59182a27
Romɑn
Aleksandr
Pavel
Aleksandr
Aleksandr
Половина коллекций из BCL - это они, вторая половина - интерфейсы и базовые классы для создания коллекций собственных
Dr. Friedrich
Dr. Friedrich
Вроде бы вообще совсем разные технологии-то?
Dr. Friedrich
Dr. Friedrich
Ayrat
Чёт какая-то херня
Это не я предложил мейлбокс Датафлоу заменять, заметь. Я вообще за его использование. Годная, простая абстракция
Ayrat
Оверхед на ЦПУ задачах общая беда фшарп асинков, но это ограничение асинхронного подхода в целом.
Nikolay
@omgszer как сделать заглушку для kprintf? В дебаге юзаем обычный kprintf, а в релизе kprintf заглушку, которая не генрерит строки, но и не ломает код. Я чет не могу допереть
Dr. Friedrich
Dr. Friedrich
Адово и получится!
Nikolay
Как?
Nikolay
Скопипастить printf.fs?
Nikolay
Или как его там
Nikolay
Я чет немного смотрел, вникал, там вроде нужные классы internal
Aleksandr
Свои такие написать не получится
Aleksandr
Там типизиация хэндлится самим компилятором
Dr. Friedrich
let myLog =
if debug then ignore
else Printf.kprintf
Dr. Friedrich
Nikolay
Dr. Friedrich
А чо будет?
Dr. Friedrich
Блин, да, там какой-то ад. Придётся думоть!
Aleksandr
Заменить на ksprintf и в континуэйшн пихать либо логгер либо игнор
Nikolay
интрестинг
Dr. Friedrich
Там странная сигнатура у него, но, вроде, раскурить можно
Pavel
тогда уж так
Pavel
let myLog =
#if DEBUG
ignore
#else
Printf.kprintf
#endif
Pavel
или наоборот
Dr. Friedrich
или наоборот
Ну да, на самом деле надо наоборот, это я в своём примере ошибся :)
Vladimir
ещё есть вариант не юзать kprintf :)
Aleksandr
Pavel
так же как и тут let myLog =
if debug then ignore
else Printf.kprintf
Pavel
ему какая разница?
Dr. Friedrich
Pavel
блин.. ща студию заведу
Aleksandr
Он выводится по особому
Dr. Friedrich
Играюсь вот с этим сэмплом, но пока не понял, как заинлайнить логгер внутрь logPrintf
Dr. Friedrich
О, вроде вышло, щас покажу.
Pavel
let myLog (x : '_a when '_a :> Printf.StringFormat<'_b,unit>) =
#if ! DEBUG
Printf.kprintf (printfn "%s") x
#else
Unchecked.defaultof<_>
#endif
Pavel
myLog "%s sss %i" "aa" 11 не чет не так
Dr. Friedrich
open System
let mutable debug = true
let debugLog (format: Printf.StringFormat<'a, unit>): 'a =
Printf.kprintf (
fun s -> if debug then printfn "%A: %s" DateTime.Now s
) format
[<EntryPoint>]
let main _ =
debugLog "This: %s" "foo"
debugLog "That: %d - %d = %d" 2 2 4
debug <- false
debugLog "Invisible! %s" "haha"
debug <- true
debugLog "Visible"
0
Nikolay
Nikolay
Строка то все равно аллоцируется
Dr. Friedrich
Хм.
Dr. Friedrich
Мне кажется, что ты по-другому не сделаешь
Dr. Friedrich
Да, строка, которая передаётся в лямбдочку, всегда зааллоцируется.
Dr. Friedrich
Dr. Friedrich
А хотя…
Dr. Friedrich
В каком месте вообще аллоцируется строка? Printf.StringFormat уже это сделал или ещё нет?
Nikolay
Dr. Friedrich
Слушай, вроде нет
Dr. Friedrich
Dr. Friedrich
Там нельзя возвращать Unchecked.defaultof, потому что эта штука в обычной ситуации возвращает функцию
Dr. Friedrich
И её снаружи пытаются вызвать, передав аргументы
Dr. Friedrich
Щя я сделаю.
Dr. Friedrich
Короче, я придумал, как сделать, но делать мне неохота. Попробуй заполнить тудушку :)
let inline negate<'a>(): 'a =
printfn "%A" <| typeof<'a>
if typedefof<'a> = typedefof<FSharpFunc<_, _>> then
// TODO: Generate a function of right type (see typeof<'a>.GetGenericTypeArguments()) that will ignore everything and return negate<> as its result
else // terminal case, unit
Unchecked.defaultof<_>
let debugLog format =
if debug then
Printf.kprintf (
printfn "%A: %s" DateTime.Now
) format
else negate()
Dr. Friedrich
Я верю, что это можно сделать с кэшом, чтобы был zero-alloc на длинной дистанции
Nikolay
Dr. Friedrich
Nikolay
Я старался!
А там получается функция с любым количеством аргументов?
Dr. Friedrich
На самом деле точно не с любым, потому что чисто физически количество типоаргументов в FSharpFunc ограничено.
Nikolay
Дмитрий
можно на лямбдах и их инлайнинге по идее сделать то что нужно