LINUX.ORG.RU

Garnet - кэш от Microsoft, написан на C#, делает и Redis, и Dragonfly

 , , garnet, ,


0

5

Как видно из бенчмарков, это сейчас вообще самый быстрый сервер структур данных на всём диком западе:

https://microsoft.github.io/garnet/docs/benchmarking/results-resp-bench

Парктически полностью совместим с Redis на уровне API, но при этом:

  • Имеет либеральную MIT лицензию, как и все последние крупные проекты MS, и этим крайне выгодно отличается от Redis
  • Написан на C#, и позволяет удобно расширять сервер
  • Делает по производительности и Redis, написанный на Си, и Dragonfly написанный на C++

Последний пункт особенно забавен, надеюсь хоть это у крестолюбцев в голове что-либо прочистит, и вот это дебильное мнение что «сипласплас эта быстра», а также глупые наезды на GC, наконец канут в лету. Кресты в современном мире нахер не нужны, и никакой даже особой производительности не дают. Да и Си, в принципе, тоже нигде не нужен выше уровня ядра.

Я кстати, в свое время написал на C# видеостриминг-сервер, и клиент, практически не используя кресты(было немного C++/CLI для связи с COM итд), и проблем с производительностью там не было. Но что я - вон целый MS Research делает продукты вон какого уровня.

★★

Ответ на: комментарий от alysnix

я не против повышения производительности разработчика, я против того что шарп производительней. потому что это кровавая ложь

Ну если джуновый-мидловый плюсовик начнёт велосипедить какую-нибудь хрень, которую .NET генерит автоматически, я даже и не удивлюсь, если плюсовый говнокод будет тормознее, чем выхлоп шарпа или VB.NET, потому что отдельные фрагменты .NET оптимизированы вплоть до ручного кода Майковых разработчиков на асме.

А кто-то считал, сколько всего в мире понаписано плюсового говнокода? Ведь настоящий плюсовый профи стоит огого сколько денег, и то может облажаться время от времени, ведь он человек, а не детерминированный робот-транспайлер типа Haxe->C++.

sanyo1234
()
Последнее исправление: sanyo1234 (всего исправлений: 3)
Ответ на: комментарий от sanyo1234

потому что отдельные фрагменты .NET оптимизированы вплоть до ручного кода на асме.

А фрагменты С++ нет? У него и оптимизатор встотыщраз лучше. Я заметил, по постам в интернете, что обычно наоборот, люди которые не имеют большого опыта, удивляются насколько быстро работают их программы, когда они переписывают их на C/C++. И только имея опыт и там и там, можно нормально писать на C#, Java.

MOPKOBKA ★★★★
()
Ответ на: комментарий от sanyo1234

Я обеим сторонам таблицы ужаснулся. Слева - куча мусорного синтаксиса, справа - очевидная скриптота (и тоже местами мусорный синтаксис), примерно как js. Только у js хотя бы синтаксис понятный (сишный).

firkax ★★★★★
()
Ответ на: комментарий от alysnix

ты ж не написал, что стал другим человеком, осознал и больше такого не повторится.

Да мне уже и спрашивать то почти нечего по раздражавшим вас тематикам. Я раньше интересовался обзорными вопросами по выбору софта, это посчитали троллингом или сделали вид. А сейчас я уже сформировал большую часть списка интересовавшего меня софта (он перечислен в моём профиле) кроме пока ещё софта для организации работы Кубер кластера.

По Куберу там упомянут только k0s и talos, но и их, думаю, мне будет достаточно первое время.

sanyo1234
()
Ответ на: комментарий от alysnix

для прикладных индусов, а не системного софта

redis не особо и системный софт

если оно «кого-то» там обгоняет - эти «кто-то» подрихтуют свои алгоритмы

у Redis’а главная проблема - он однопоточный. Отсюда и производительность ниже. Dragonfly мультипоточный, быстрый, но afaik достаточно глючный.

Насколько глючный Garnet мы не знаем, но он вполне может быть быстрее, так как после того как .net core попал в gamedev, его очень сильно прокачали по производительности работы с памятью и многопоточности

adn ★★★★
()
Ответ на: комментарий от alysnix

О, нашел. Суть такова.

Real-World приложения это естественно, не хелловорлды из синтетических тестов, со вставками на асме, это раз. А два - они вовсю засраны умными указателями. В следующем тесте я пытаюсь эмулировать реальное приложение на C++(смотрите сорцы вебкита, ггг), C# и лиспе соответственно, с кучей типа «умных» объектов, с коллекциями этих объектов, а не просто матрицами на стеке, итд, в наиболее нативном виде для языка как он используется в больших системах, а не на хелловорлдах. Песни про оптимизации и закатывание солнца вручную, поэтому, засуньте себе в жопу, тест не про это.

Лисповый код собирать так: sbcl --no-userinit --no-sysinit --load test-sbcl.lisp

(declaim (optimize (speed 3) (safety 0)))

(defun copy-vector (vector)
  (declare (type simple-vector vector))
  (let* ((length (length vector))
         (new-vector (make-array length)))
    (dotimes (i length)
      (setf (svref new-vector i) (svref vector i)))
    new-vector))

(defun test (n length)
  (declare (type fixnum length n))
  (let ((vector (make-array length)))
    (dotimes (i length)
      (setf (svref vector i) (cons nil nil)))
    (dotimes (i n)
      (setf vector (copy-vector vector)))))

(defun main (&aux (n (second sb-ext:*posix-argv*))
                  (length (third sb-ext:*posix-argv*)))
  (when (> (length sb-ext:*posix-argv*) 3)
    (write-line "Usage test_sbcl [ n [ length ] ]")
    (sb-ext:quit :unix-status 1))
  (let ((n (or (and n (parse-integer n))
               1000000))
        (length (or (and length (parse-integer length))
                    100)))
    (declare (type fixnum n length))
    (test n length))
  (sb-ext:gc :full t))

(sb-ext:save-lisp-and-die "test_sbcl"
                          :executable t
                          :toplevel #'main)

Крестовый код собирать так: gcc -O2 -o test_cpp test_cpp.cxx

#include <cstdlib>
#include <vector>
#include <iostream>
#include <memory>

struct Cons
{
    void* car;
    void* cdr;
    Cons(void* _car, void* _cdr)
    {
        car = _car;
        cdr = _cdr;
    }
};

typedef std::shared_ptr<Cons> ConsPtr;
typedef std::vector<ConsPtr> ConsPtrVector;
typedef std::shared_ptr<ConsPtrVector> ConsPtrVectorPtr;

ConsPtrVectorPtr CopyVector(ConsPtrVectorPtr vec)
{
    int length = vec->size();
    ConsPtrVectorPtr copy(new ConsPtrVector(length));
    for(int i = 0; i<length; ++i)
    {
        (*copy)[i]  = (*vec)[i];
    }
    return copy;
}

void Test(int n, int length)
{
    ConsPtrVectorPtr vec(new ConsPtrVector(length));
    for(int i = 0; i<length; ++i)
    {
        ConsPtr ptr(new Cons(NULL, NULL));
        (*vec)[i] = ptr;
    }
    for(int i = 0; i<n; ++i)
    {
        ConsPtrVectorPtr copy = CopyVector(vec);
        vec.swap(copy);
    }
}

int main(int argc, char** argv)
{
    int n = 1000000, length = 100;
    switch(argc)
    {
        case 1:
            break;
        case 2:
            if((n = atoi(argv[1])) <= 0)
            {
                std::cout << "Invalid parameter: " << argv[1] << std::endl;
                return 1;
            }
            break;
        case 3:
            if((n = atoi(argv[1])) <= 0)
            {
                std::cout << "Invalid parameter: " << argv[1] << std::endl;
                return 1;
            }
            if((length = atoi(argv[2])) <= 0)
            {
                std::cout << "Invalid parameter: " << argv[2] << std::endl;
                return 1;
            }
            break;
        default:
            std::cout << "Usage: test_cpp [ n [ length ] ]" << std::endl;
            return 1;
    }
    Test(n, length);
    return 0;
}

Код на C# собирать примерно так: dotnet publish -c Release -r linux-x64 -p:PublishSingleFile=true --self-contained true -o ./ TestCsharp.csproj

namespace TestCSharp
{
    public record Cons(object? Car, object? Cdr);

    public static class Program
    {
        public static Cons[] CopyVector(Cons[] vec)
        {
            var len = vec.Length;
            var copy = new Cons[len];
            for (var i = 0; i < len; i++)
            {
                copy[i] = vec[i];
            }
            return copy;
        }

        public static void Test(int n, int length)
        {
            var vec = new Cons[length];
            for (var i = 0; i < length; i++)
            {
                vec[i] = new Cons(null, null);
            }

            for (var i = 0; i < n; ++i)
            {
                var copy = CopyVector(vec);
                vec = copy;
            }
        }

        public static int Main(string[] args)
        {
            int n = 1000000, length = 100;

            switch (args.Length)
            {
                case 0:
                    break;
                case 1:
                    n = int.Parse(args[0]);
                    break;
                case 2:
                    n = int.Parse(args[0]);
                    length = int.Parse(args[1]);
                    break;
                default:
                    Console.Error.WriteLine("Usage: test_csharp [n [length]]");
                    return 1;
            }
            Test(n, length);
            return 0;
        }
    }
}

Результат такой, ггг:

lovesan@ubuntu:~$ time ./test_sbcl 1000000 1000

real    0m1.077s
user    0m1.047s
sys     0m0.030s
lovesan@ubuntu:~$ time ./TestCSharp 1000000 1000

real    0m2.312s
user    0m2.264s
sys     0m0.010s
lovesan@ubuntu:~$ time ./test_cpp 1000000 1000

real    0m3.233s
user    0m3.228s
sys     0m0.000s

То есть, кресты в ТРИ раза медленнее лиспа, и при этом в полтора раза медленнее C#. И в реальных системах, так и происходит. Даже еще хуже. Кто с крестами работал, и с крестолюбцами, тот в цирке не смеется.

lovesan ★★
() автор топика

Наезды на сборщик мусора не глупые. Он создает в играх фризы. Для вебни в принципе нормальная ситуация с подлагиванием всего и вся, ведь страницы давно грузятся по паре секунд. Не верю, что «делает», а вот то что подобную вещь на чем угодно можно написать…

anonymous
()
Ответ на: комментарий от lovesan

Даже еще хуже. Кто с крестами работал, и с крестолюбцами,

Я работал в ПФР с крестолюбцем.

Сам я на плюсах кодил только в юности лет 30 назад, тогда выбор был не шибко большой, но даже тогда уже было очевидно, что Clipper CA 5.01 для разработки прикладнухи продуктивнее раз в 100.

Сейчас это было бы что-то похожее на https://www.xsharp.eu/

тот в цирке не смеется.

И как раз в цирке.

Так что вообще не смешно совсем …

Он даже отчётные формы в Excel готовил через Excel ActiveX интерфейс + Visual C++

sanyo1234
()
Последнее исправление: sanyo1234 (всего исправлений: 6)
Ответ на: комментарий от anonymous

По словам Claude.ai:

Here are some key points about garbage collection in .NET Native AOT-compiled binaries:

    GC Design: The .NET Native GC is designed to be simpler and more predictable than the traditional .NET GC. It uses a non-compacting, mark-and-sweep algorithm, which avoids the need for compaction and simplifies the GC implementation.
    AOT Compilation: During the AOT compilation process, the compiler analyzes the code and generates GC information and metadata that is embedded in the final binary. This metadata is used by the AOT GC at runtime.
    GC Triggering: The AOT GC is triggered based on a simple threshold mechanism. When the amount of allocated memory crosses a predefined threshold, the GC is triggered to reclaim unused memory.
    Thread Suspension: Unlike the traditional .NET GC, which suspends all threads during a collection, the .NET Native GC uses a concurrent marking phase that allows threads to continue running during most of the collection cycle.
    Memory Layout: The .NET Native GC uses a different memory layout compared to the traditional .NET runtime. It separates the managed heap into different regions, including the new object space, the large object space, and the pinned object space.
    Performance Characteristics: The .NET Native GC is designed to be more deterministic and predictable in terms of performance, at the cost of some throughput compared to the traditional .NET GC. This predictability is important for scenarios like ahead-of-time compiled apps, where consistent performance is crucial.

Btw., следующий релиз .NET v9 нацелен на cloud-native приложения, наверно, Goкрыс на мороз будут выпинывать?

sanyo1234
()
Последнее исправление: sanyo1234 (всего исправлений: 2)

Имеет либеральную MIT лицензию, как и все последние крупные проекты MS, и этим крайне выгодно отличается от Redis

Времена ныне такие, что сегодня «Имеет либеральную MIT лицензию», а завтра запрет на использование в списке стран.
Тем более это Microsoft.
ИМХО не советовал бы полагаться на их технологии.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 2)
Ответ на: комментарий от lovesan

То есть, кресты в ТРИ раза медленнее лиспа, и при этом в полтора раза медленнее C#. И в реальных системах, так и происходит. Даже еще хуже. Кто с крестами работал, и с крестолюбцами, тот в цирке не смеется.

Легким движением руки:

void Test(std::size_t n, std::size_t length)
{
    ConsPtrVectorPtr vec = std::make_shared<ConsPtrVector>();
    vec->reserve(length);
    for(std::size_t i = 0; i<length; ++i)
    {
        vec->push_back(std::make_shared<Cons>(nullptr, nullptr));
    }
    for(std::size_t i = 0; i<n; ++i)
    {
        ConsPtrVectorPtr copy = std::make_shared<ConsPtrVector>(*vec);
        vec.swap(copy);
    }
}

и

$ time ./lavsan 1000000 1000

real    0m3,568s
user    0m3,564s
sys     0m0,004s

$ time ./make_shared 1000000 1000

real    0m2,690s
user    0m2,687s
sys     0m0,004s
eao197 ★★★★★
()
Ответ на: комментарий от lovesan

То есть, кресты в ТРИ раза медленнее лиспа,

для начала в с++ убери SharedPtr для указателя на cons пару, потому, что это тряхом… есть указатель со счетчиком ссылок, а не просто указатель как в лиспе или шарпе.

alysnix ★★★
()
Ответ на: комментарий от alysnix

Cons-ячейка здесь должна быть объектом в памяти, который доступен через указатель. Не важно что это тут она такая простая. В реальности это может не ячейка, а какая-нибудь хитрожопая херота, типа графа объектов HTML нодов где-нибудь внутри вебкита. И соответственно, проход по вектору тут эмулирует сложные случаи доступа к сложным объектам, а не копирование, блять, вектора, как вон этот выпускник бобруйского государственного по-глупости подумал.

lovesan ★★
() автор топика
Ответ на: комментарий от alysnix

ConsPtrVectorPtr copy(new ConsPtrVector(length));

эта фигня и все фигни такого рода будут не только резервировать, но и запускать дефолтные конструкторы всех length элементов. что совсем не нужно в данном случае. и чем сложней конструктор элемента, тем больше времени это займет.

в лиспе наверняка такого не будет. про шарп не знаю.

alysnix ★★★
()
Ответ на: комментарий от alysnix

Честный вопрос: сколько в крестах таких магических штук, работающих быстрее наивного кода, и сколько лет опыта нужно, чтобы на гора выдавать код, сопоставимый (как показывает пример от eao) с наивным кодом на шарпе?

Midael ★★★★★
()
Ответ на: комментарий от Forum0888

Времена ныне такие, что сегодня «Имеет либеральную MIT лицензию», а завтра запрет на использование в списке стран. Тем более это Microsoft. ИМХО не советовал бы полагаться на их технологии.

Остальные технологии чем отличаются?

Спонсоры не могут поменять лицуху на Java, Rust, GCC, LLVM, Linux, Debian, etc. ?

У Астры всё хорошо в правовом поле за пределами РФ?

sanyo1234
()
Ответ на: комментарий от Midael

использование shared_ptr в данном случае - это антипаттерн. тут надо использовать обычный указатель, как это будет в лиспе.

shared_ptr - это управление ресурсом на основе счета ссылок. тут это вообще не надо.

использование векторов - тоже не надо. по крайней мере в лисповом коде это похоже просто массив. вот и используй массив и тут.

alysnix ★★★
()
Ответ на: комментарий от lovesan

Зачем ты меняешь суть программы?

Программа делает тоже самое, что и исходная. Но быстрее, и код компактнее.

Ты не понял, про что тест?

Про стоимость динамической аллокации и деаллокации памяти. Ну так она никуда и не делась.

Было бы интересно другое. Вот некто lovesan сказал:

Синтетические тесты в вакууме - говно на палочке

А потом этот же lovesan бах! И синтетический тест в качестве доказательства.

eao197 ★★★★★
()
Ответ на: комментарий от lovesan

Потому что крестовики принципиально не понимают что такое производительность, откуда она берется и так далее. И еще верят в то что «сипласплас это быстра». Прям магия какая-то, вот взяли C++ и стало «быстра»(и почему только в реальных приложениях на крестах все наоборот?).

И все гонят и гонят, пургу.

slew
()
Ответ на: комментарий от slew

Неосилившые плюсы вечно какую-то пургу гонят.

Неосилившие понимание того, что выбор удобного инструмента никак не связан с превозмоганием и осиливанием плюсов, systemd на хостах гипервизоров, наркоты, ЛГБТ, etc. делают вид, что очень крутые кодеры, а другие прям неспособны кодить на их ассемблерах от слова ass.

Но прикинь, просто не хочется. Тебе наверно не осилить такую простую истину?

sanyo1234
()
Ответ на: комментарий от Midael

Честный вопрос: сколько в крестах таких магических штук

В приведенном примере нет никаких магических штук. За реально магическими штуками нужно, например, вот сюда.

Здесь достаточно просто понимания того, как работает std::vector. И чем отличается std::shared_ptr<T> a{new T()} от std::shared_ptr<T> a = std::make_shared<T>().

ИМХО, для C++ника такое понимание необходимо. Если только он не Qt-шный формошлепщик.

eao197 ★★★★★
()
Ответ на: комментарий от sanyo1234

Но прикинь, просто не хочется. Тебе наверно не осилить такую простую истину?

Мне вот просто интересно: а что, где-то заставляют программировать на C++?

Друг просто интересуется (c)

eao197 ★★★★★
()
Ответ на: комментарий от sanyo1234

Ты куда-то не в ту степь попер. Нафиг никто не вперся, осилил он чего или нет, и нужно оно ему или нет, пока не начинает нести пургу именно про то, чего неосилил и о чем не имеет представления именно потому, что неосилил. Андерстенд?

slew
()
Ответ на: комментарий от anonymous

Вы не смогли купить Астру в Грузии

Лично мне на данный момент времени Астра не нужна даже в РФ.

или кто-то в Латвии подал в суд на РусБИТех?

Во Франции около 10 лет ждали решения суда?

sanyo1234
()
Ответ на: комментарий от slew

Ты куда-то не в ту степь попер. Нафиг никто не вперся, осилил он чего или нет,

Ты вроде вот про осилить 5 минут назад писал, и уже переобулся в полёте?

и нужно оно ему или нет, пока не начинает нести пургу именно про то, чего неосилил

Под неосиляторством обычно понимается неуспешная попытка овладеть инструментом? Но ведь бывает и так, что человек овладел инструментом, но понял, что есть и другие инструменты значительно лучше?

и о чем не имеет представления именно потому, что неосилил.

Ну это ведь твои фантазии, неподтвержденные ничем.

Андерстенд?

Do you speak English?

sanyo1234
()
Ответ на: комментарий от anonymous

Во Франции около 10 лет ждали решения суда по Астре?

Нет, не по Астре, а по кейсу нарушения условий свободной лицензии.

Штраф там такой влупили, сколько вам вероятно не заработать за всю жизнь.

sanyo1234
()
Ответ на: комментарий от Midael

Он не каких-то магических штук добавил, он тупо удалил часть логики, демонстрирующей суть. Т.к. не понял нихера, о чем пример, впрочем крестолюбцы они такие, туповатые.

lovesan ★★
() автор топика
Ответ на: комментарий от sanyo1234

Нет, не по Астре, а по кейсу нарушения условий свободной лицензии.

Судили РусБИТех? Если нет, то хотелось бы понять, почему вы так сильно переживаете о судьбе ОС, которую продают исключительно российским юрлицам, во Франции?

anonymous
()